Media folder files created with wrong permissions


I have a Kirby site running on a php 7.4.3 server that is creating files and folders under media folder as 600/700, so they return 403 when being accessed via the browser.

This only happens in this particular server, wile not happening in two other php 8+ servers BUT in this particular server there are many other, mostly WP, sites, where Apache is creating files with 644/755

To make things even more complicated to troubleshoot, this site of mine is using Erlega, a theme that works as a plugin.

There are a couple other plugins on this site, such as:

socialmusemedia/erlega-theme 1.0.5
schnti/cachebuster (deactivated)
hananils/kirby-colors 1.7.0
bnomei/kirby3-fontselector 1.1.1
oblik/kirby-link-field 5.2.2
omz13/kirby3-xmlsitemap 1.2.1

Can someone perhaps give a direction on how to troubleshoot this? Why this site on this server, but not this site in other servers, or other sites in this server, what can trigger this combination?

What handles, in kirby, permissions? Does Kirby has a panel config option to set preferred file permissions. In the past someone talked about this here.

Why would Kirby use different permissions to those apparently set up for Apache in this server? How to troubleshoot this?

Thank you

I’ve been checking this, and I confirmed the server has a restrictive umask on apache’s user, that effectively creates files with insufficient permissions.

And I told them admins, who were saying “no no no no” and now it is “yes yes yes”, so… not Kirby’s fault :woman_shrugging:

I am reopening this, because, although Apache’s user umask on this server is restrictive, there are about 300 other (not static) websites using WP or Drupal that do not have permissions problems on newly created files, on the same server

And while creating a file directly with plain PHP results on 600 permissions, if I use chmod() afterward, I can successfully set the right permissions:

$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
chmod("newfile.txt", 0644);

I can only assume that the other CMS are doing this automatically ? Is there any way to force Kirby to ensure that perms are 644/755 or similar after writing them ?

Anybody with knowledge on this matter? @texnixe bitte?

Thank you very much.

Kirby uses PHP’s own mkdir() function without any other arguments than the directory path. The default value for the permissions parameter is 0777. I quote from the PHP docs:

The mode is 0777 by default, which means the widest possible access. For more information on modes, read the details on the chmod page.
mode is ignored on Windows.
Note that you probably want to specify the mode as an octal number, which means it should have a leading zero. The mode is also modified by the current umask, which you can change using umask()

In this server, Kirby creates folders as 700 and files as 600 , both under /content and /media, so they cannot be accessed through the browser and return 403.

That is surely caused by Apache’s user umask being restricted on this server.

BUT, as said, WP and Drupal are working normally in this server AND with plain PHP I can chmod() after creating a folder or a file, to get the right permissions.

With your answer you are telling me there is no actual way to force a chmod of the files after writing, is this correct @texnixe ?

Can you think of any possible workaround? I am perplexed by this server and the ability of other CMS to deal with it.


Well, I don’t know what WP or Drupal do internally, maybe they set the permissions explicitly.

Well, found what may be most probably what they use: wp-config.php | Common APIs Handbook | WordPress Developer Resources

The FS_CHMOD_DIR and FS_CHMOD_FILE define statements allow override of default file permissions. These two variables were developed in response to the problem of the core update function failing with hosts running under suexec. If a host uses restrictive file permissions (e.g. 400) for all user files, and refuses to access files which have group or world permissions set, these definitions could solve the problem.

define( 'FS_CHMOD_DIR', ( 0755 & ~ umask() ) );
define( 'FS_CHMOD_FILE', ( 0644 & ~ umask() ) );

@texnixe Should it be possible to chmod() the right permissions on a file/page/folder on a create after hook ?

In the case of files, can I get the media folder path from the file object ? or I will be getting the content folder path ?

I could recursively chmod the entire media OR content folders, but seems like hunting flies with cannons.

This is a university hosting provided free of charge to a research group. They are considering changing the server’s umask, but as every one of the other +300 sites they host works correctly, it may be that they end up not changing it, and I should try to make Kirby work then, too, if possible (as I am the one who sold the idea of using Kirby instead of WP to this client :smiley: )


Should be, but doesn’t really sound like a solution.

Hm, I don’t really know what’s the best way forward.

It is difficult to elaborate on this issue without the ability to do further checks. Some of your statements are raising questions to me:

If the webserver (not PHP server) is creating files/folders, the webserver should be able to read them which would be the case if the permissions are 600/700 because the owner of the file/folder can read and write and the owner should be the user under which the webserver is running. If this is not the case, there are some more conditions to consider, i.e. is suEXEC involved, is the server running PHP-FPM with a different user/group, are there SETUID or SETGID set in the relevant directories?

What do you mean with “plain PHP”? Did you run the mentioned script on the command line? Then it is run under different user and group compared to as when it is run from the webserver. Running a script with CLI and from the webserver might be completely different depending on the configuration on the server.

How did you test this? Did you set up a WP or Drupal installation with the same virtual host configuration in the same base directory? If not, you might compare apples with pears because the virtual host configuration of the other sites might be completely different, especially if suEXEC is really involved.

Changing the permissions programmatically sounds like the least desirable solution. Unless you are not clear of the real root cause of the issue I would not go for such a radical solution.

Thanks for your answer.

To collect contextual info: this is a university server, provided free of charge to the research group whose site I am coding. This server hosts +300 websites based on WP, Drupal, etc.

I assume that they follow the same procedure for all sites they host, and according to them, all the other sites do not have problems with permissions.

I did not test this but I already confirmed that WP has a constant that forces chmod on files and folders after writing them, so this is perfectly plausible.

It has been also confirmed by admins that the server has a restrictive umask on apache’s user, for security reasons, and that files/folders are created as 600/700. When Kirby tries to load these files, 403 errors ensue.

If I create a .php page and visit the page, I can successfully use chmod() to change permissions of files. After adding +r to other, files load correctly, and the issue is solved (well, until more content is created/uploaded).

I also have ssh access, with a superlimited shell (no chmod) and SFTP access. When using SFTP, files and folders are created with the right permissions, and I can change permissions correctly.

Perhaps this solves part of the questions you raised.

I really don’t see any other options than either they change the default permissions, a decision that apparently they are studying, or I force-chmod after writing files and folders, which seems to be the way WP does it ?

Thank you.

They do, in fact, here is some example code from WP

	public function put_contents( $file, $contents, $mode = false ) {
		$fp = @fopen( $file, 'wb' );

		if ( ! $fp ) {
			return false;


		$data_length = strlen( $contents );

		$bytes_written = fwrite( $fp, $contents );


		fclose( $fp );

		if ( $data_length !== $bytes_written ) {
			return false;

		$this->chmod( $file, $mode ); // here they call a chmod method, which internally checks the constant for the set mode.

		return true;
1 Like

:walking_woman: Quickly goes deleting WordPress from notebook…

So they changed the umask :woman_shrugging: