A 403 Forbidden error after uploading a plugin, or a 500 Internal Server Error after manually changing permissions; both usually have the same root cause: the number you wrote in chmod doesn't match the file type or the executing user. If you're looking for the exact value for a specific file, read this reference to the end; if you're looking for a step-by-step guide to creating an FTP account, the guide to creating and managing FTP accounts is a more appropriate path.
What exactly does each chmod digit control
A chmod value is a three-digit octal number where each digit belongs to a user group: the file owner, the file group, and others. Each digit is itself the sum of three bits:
- 4 = read
- 2 = write
- 1 = execute
So 6 means read and write, 5 means read and execute, 7 means all three. Break down the number 644: owner 6 (read+write), group 4 (read only), others 4 (read only). That's it.
The fourth digit that is mostly forgotten
Sometimes you see four digits, like 2755 or 1777. The first digit is the special bits:
| Digit | Name | Actual effect |
|---|---|---|
| 4 | setuid | The program runs with the identity of the file owner, not the executing user |
| 2 | setgid | On a folder: new files take the folder's group, not the creator's group |
| 1 | sticky bit | Only the file owner can delete it; its use case is /tmp |
On shared hosting, setuid on PHP files is almost always disabled, and if you rely on it, the script runs under the wrong user and uploaded files end up with inconsistent ownership.
The correct chmod value for each file type
This table can be used as a baseline on most Linux hosts:
| Type | Value | Description |
|---|---|---|
| Regular file (HTML, CSS, image) | 644 | Owner writes, others only read |
| Folder | 755 | Without the execute bit, the web server can't open the folder contents |
Config file containing a password (wp-config.php) | 600 or 640 | There's no reason for the group or others to read it |
| CGI script or executable file | 755 | Execution is needed, writing for others is not |
| WordPress uploads folder | 755 | If you set 777, any injected script can write |
| Shared temp folder | 1777 | The sticky bit prevents deletion of others' files |
Never put the execute bit on PHP files. The web server reads them through an interpreter, not by direct execution; 755 on a PHP file is just an extra attack surface.
Why 777 is the wrong answer, even when it works
When you get a permission error, the fastest way is chmod -R 777 and it usually works. The problem is that any process on the same server, under any user, gains write and execute permission on those files. On shared hosting this means a neighboring account with a simple vulnerability can overwrite your files. If you're forced to set 777 temporarily, revert to 755 immediately after testing and find the root cause.
Real commands and the flags that matter
Three commands that are used most in practice:
chmod 644 index.php
chmod -R 755 wp-content/uploads
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
The last two commands respect the difference between files and folders, which is exactly what chmod -R 755 on everything breaks: files get the execute bit and folders stay correct, but config files also become 755.
To see the current value, ls -l gives symbolic output (-rw-r--r--) and stat -c "%a %n" wp-config.php gives the raw number. If ownership is wrong, chmod won't help; you need to run chown user:group file, and on shared hosting this is usually only possible through support.
umask: why a new file is created with 644
The default value for new files comes from umask. If umask is 022, a new file becomes 666 - 022 = 644 and a new folder becomes 777 - 022 = 755. With umask set to 027, files are created as 640 and folders as 750. If you have to manually run chmod after every upload, the problem is probably umask or the ownership of the PHP process, not the file permissions.
Where people go wrong
The most common mistake I see is someone running chmod -R 777 on the entire site folder to fix a 500 error. The error goes away, the site comes up, and two weeks later the site shows up with an unknown redirect to another domain or with unknown files in wp-content. The telltale sign: files with the same modification date in a folder you didn't touch yourself, or wp-config.php with a value of 777 in the ls -l output. If you see this, first revert the permissions, then compare the files against a clean copy.
The second mistake is subtler: some people think chmod affects ownership. It doesn't. A file owned by root with 777 permissions is still writable by the www-data user, but for a script running under a different user it may have trouble deleting or renaming it. If you get a Permission denied error on a delete operation, the problem is the ownership of the parent folder, not the permissions of the file itself.
When permissions are correct but the site still errors
If permissions are set to 644 and 755 and you still see a white screen, the problem is elsewhere. The guide to fixing the white screen in WordPress and PHP covers the troubleshooting path step by step. If the site is slow and you're hitting resource limits, the hosting resource limits reference explains what each number counts.
For a test environment or an admin panel you don't want to be public, web server authentication takes the place of chmod; the method is covered in password-protecting folders on hosting. And if you're working on a dedicated server, setfacl and ACLs give more precise options than the three-digit model, which can be used on a dedicated server.
One practical tip: before any bulk change, save the output of find . -printf "%m %p\n" | sort. Reverting permissions without a backup of the original state is more painful than the error itself.
Frequently asked questions
Is chmod 755 correct for a file, or 644?
For a regular file, 644 is correct, and 755 is only for executable scripts or folders. If you set a PHP file to 755, the site works, but the execute bit is opened for everyone, which increases the attack surface.
What's the difference between 755 and 775?
In 755 the group only reads and executes; in 775 the group also has write permission. On shared hosting where the file group is shared with other users, 775 means they can modify your file. 755 is the safer choice.
Why do I still get a permission error after chmod 777?
Because the problem is ownership, not permissions. If the file is owned by another user or the parent folder lacks the execute bit, 777 won't help either. Check the output of ls -l and namei -l /path/to/file.
What should the chmod value for wp-config.php be?
600 or 640 is enough. This file holds the database password and no other user should be able to read it. If WordPress errors with 600, it means the file ownership doesn't match the user running PHP, and you need to fix ownership, not open up the permissions.