CHMOD
chmod Linux Permission Modifier
The "Why": What's the Big Deal with Permissions?
On your WordPress VPS, chmod (which means "change mode") is the command that sets the rules for who can read, write, or **execute a file or directory.
Getting this right is a balancing act:
- **Too Strict: Your plugins can't update, and you get errors like "Upload failed. Could not create directory."
- **Too Loose: You expose your server to being hacked, allowing an attacker to upload a malicious script or steal your database passwords from
wp-config.php.
The #1 Mistake to Avoid:
You will see tutorials telling you to run chmod -R 777 on a folder.
NEVER do this on a live site.
777gives everyone (the owner, the group, and all other users) full permission to read, write, and execute files. It's like leaving your front door wide open with a sign that says "Come on in!"
Part 1: The 3-Command Quick Fix
For 90% of WordPress sites, these three commands will set safe, standard permissions. Run them from your site's main directory (often called public_html or similar).
Replace [SITE_PATH] with the full path to your site's root.
Bash
# Example: [SITE_PATH] might be /var/www/html or /home/myuser/public_html
# 1. Set all directories to 755 (drwxr-xr-x)
find [SITE_PATH] -type d -exec chmod 755 {} ;
# 2. Set all files to 644 (-rw-r--r--)
find [SITE_PATH] -type f -exec chmod 644 {} ;
# 3. Secure your most sensitive file
chmod 640 [SITE_PATH]/wp-config.php
These commands will likely fix most common permission-related errors. Now, let's understand why this works.
A Clear Guide to chmod for WordPress
This guide is structured to be learned, not just referenced. We'll start with an immediate, safe fix and then explain why it works.
The "Why": What's the Big Deal with Permissions?
On your WordPress VPS, chmod (which means "change mode") is the command that sets the rules for who can read, write, or **execute a file or directory.
Getting this right is a balancing act:
- **Too Strict: Your plugins can't update, and you get errors like "Upload failed. Could not create directory."
- **Too Loose: You expose your server to being hacked, allowing an attacker to upload a malicious script or steal your database passwords from
wp-config.php.
The #1 Mistake to Avoid:
You will see tutorials telling you to run chmod -R 777 on a folder.
NEVER do this on a live site.
777gives everyone (the owner, the group, and all other users) full permission to read, write, and execute files. It's like leaving your front door wide open with a sign that says "Come on in!"
Part 1: The 3-Command Quick Fix
For 90% of WordPress sites, these three commands will set safe, standard permissions. Run them from your site's main directory (often called public_html or similar).
Replace [SITE_PATH] with the full path to your site's root.
Bash
# Example: [SITE_PATH] might be /var/www/html or /home/myuser/public_html
# 1. Set all directories to 755 (drwxr-xr-x)
find [SITE_PATH] -type d -exec chmod 755 {} ;
# 2. Set all files to 644 (-rw-r--r--)
find [SITE_PATH] -type f -exec chmod 644 {} ;
# 3. Secure your most sensitive file
chmod 640 [SITE_PATH]/wp-config.php
These commands will likely fix most common permission-related errors. Now, let's understand why this works.
Part 2: The Core Concepts (Why 755 & 644?)
This is the most important part of the lesson. Permissions are set for three different "classes" of users.
The Three Groups
- **Owner (u): The user who owns the file (e.g., your personal user account, like
myuser). - **Group (g): A group of users. On a server, this is often the web server itself (e.g.,
www-data,apache, orlshttp). - **Others (o): Everyone else. This includes all other users on the system and public visitors.
The Three Permissions
- **Read (r): The permission to see the contents.
- **Write (w): The permission to change the contents.
- **Execute (x): The permission to run the file (or enter a directory).
The "Aha!" Moment: Permissions Mean Different Things for Files vs. Directories
This is the #1 point of confusion, and understanding it makes everything clear.
| Permission | For a File (e.g., index.php) | For a Directory (e.g., wp-content/uploads) |
|---|---|---|
| Read (r) | Can open and read the file's contents. | Can list the files inside the directory (e.g., using ls). |
| Write (w) | Can modify or delete the file. | Can create, rename, or delete files within the directory. |
| Execute (x) | Can run the file as a program or script. | Can enter (i.e., cd) into the directory. |
This is why directories need x (Execute)!
If you remove x from the wp-content/uploads directory, your web server can't "enter" it to find an image, even if it has "Read" permission. This is what causes many "File not found" or "Permission denied" errors.
This covers the most critical foundation. You now have a safe recipe and a clear understanding of what you're changing.
When you're ready, we can move on to Part 3, where we'll cover:
- **How to read the "numbers" (What
755and644actually mean). - **The "letters" syntax (e.g.,
chmod u+x), which is great for making small changes.
Here is Part 3, where we'll cover the two different ways to tell chmod what to do.
Part 3: The "How-To" (Numbers vs. Letters)
You now know why you need rwx permissions for the Owner, Group, and Others. But how do you tell the chmod command to set them?
There are two methods. You will see both in online tutorials, so it's important to understand them.
Method 1: Numeric (Octal) Mode (e.g., 755)
This is the most common method. It's a fast shortcut that uses numbers as a code for rwx.
The Math is Simple:
r(Read) = 4w(Write) = 2x(Execute) = 1- (No permission) = 0
You just add the numbers together for each of the three groups (Owner, Group, Others).
| Number | Permissions | What it means |
|---|---|---|
| 7 | rwx (4+2+1) | Full permissions. |
| 6 | rw- (4+2+0) | Read and Write. |
| 5 | r-x (4+0+1) | Read and Execute. |
| 4 | r-- (4+0+0) | Read only. |
| 0 | --- (0+0+0) | No permissions. |
Let's Revisit Our "Quick Fix" Commands:
**chmod 755 [directory]**
- **Owner: gets **7 (
rwx) - You can read, write, and enter the directory. - **Group: gets **5 (
r-x) - The web server can read and enter the directory, but not create/delete files. - **Others: gets **5 (
r-x) - Everyone else can read and enter the directory.
Why it's good for directories: The x (execute) is what allows everyone to enter the directory.
**chmod 644 [file]**
- **Owner: gets **6 (
rw-) - You can read and write (edit) the file. - **Group: gets **4 (
r--) - The web server can read the file, but not edit or run it. - **Others: gets **4 (
r--) - Everyone else can read the file.
Why it's good for files: No one gets x (execute) permission. This is a critical security feature. You don't want a hacker to be able to "run" one of your image files as a script.
**chmod 640 [SITE_PATH]/wp-config.php**
- **Owner: gets **6 (
rw-) - You can read and edit the file. - **Group: gets **4 (
r--) - The web server can read the file (it needs to!). - **Others: gets **0 (
--) - Everyone else gets NO permissions.
Why it's good for wp-config.php: This is your most sensitive file. This command makes it completely invisible to "Others," strongly protecting your database password.
Method 2: Symbolic (Letter) Mode (e.g., u+x)
This method is less common for setting up a whole site, but it's excellent for making small, specific changes.
The format is:
chmod [Who][Action][Permission] [file]
- Who?
u(user/owner)g(group)o(others)a(all)- Action?
+(add a permission)- (remove a permission)
=(set the permission exactly)- Permission?
r(read)w(write)x(execute)
Practical Examples:
-
You just wrote a shell script and need to make it executable for yourself:Bash
chmod u+x my_script.sh -
You want to make sure your
wp-config.phpis not writable by the group:Bashchmod g-w wp-config.php -
You want to add read/write permission for the group, but leave the owner and others alone:Bash
chmod g+rw some_file.txt -
You want to set a file so the owner can read/write, and everyone else (group and others) can only read:Bash
chmod u=rw,go=r some_file.txt
A Warning About Recursive Changes (R)
You will often see the -R (recursive) flag, which applies a command to a directory and everything inside it.
chmod -R 755 [directory]
**This is DANGEROUS. If you run chmod -R 755 ., you will give all your files x (execute) permission. If you run chmod -R 644 ., you will remove the x (execute) permission from all your directories, breaking your entire site.
This is exactly why our Part 1 "Quick Fix" used the find command. It lets us apply 755 only to directories and 644 only to files.
The One Safe "Recursive" Trick:
There is a special permission, capital X. It's a "smart execute" that only adds x to directories and files that already have execute permission (like scripts).
If you want to make sure all your directories are executable for everyone without touching your files, this is a very safe and useful command:
Bash
# Add 'execute' permission for all users, but only on directories.
chmod -R a+X [directory]
You now know the "why," the "what," and the "how." You have all the skills needed to safely manage your site's permissions.
Part 4: The Pro Workflow (Audit Plan Apply Verify)
Instead of just running commands, a pro first diagnoses the problem, plans the fix, applies it, and verifies that it worked (and didn't break anything else).
Step 1: Audit (Look Before You Leap)
Never start applying fixes until you know the current state. You might be fixing the wrong problem.
Run these commands from your site's root path ([SITE_PATH]).
- Check Key File and Directory Permissions
This command finds all your directories (-type d) and files (-type f), finds the unique permission modes (-printf '%m' | sort -u), and shows you a count of each.
Bash
# See what modes your directories have
find [SITE_PATH] -type d -printf '%mn' | sort -u
# See what modes your files have
find [SITE_PATH] -type f -printf '%mn' | sort -u
Expected Output (Good):
755
644
Example Output (Bad):
If you see 777, 666, or a huge mix of numbers, you know you have a problem.
- Check a Specific, Important File
The stat command is a detailed "statistics" report for a file.
Bash
# Check your wp-config.php file
stat -c '%a %U:%G %n' [SITE_PATH]/wp-config.php
What this command means:
%a: Show permissions in octal (e.g.,640)%U: Show the Owner's username (e.g.,myuser)%G: Show the Group's name (e.g.,www-data)%n: Show the file name
Expected Output:
640 myuser:www-data /var/www/html/wp-config.php
Red Flags:
644or666: Too loose! "Others" can read it.root:root: Your web server (www-data) probably can't read this, and your site will be broken.
Step 2: Plan (Know Your Goal)
Now that you've audited, you can make a plan. For 99% of WordPress sites, the plan is to follow these "safe defaults."
| Path / Target | Recommended Mode | Rationale (The "Why") |
|---|---|---|
| All directories | 755 | rwxr-xr-x: Owner can do anything. Group/Others can enter (x) and list (r) but not write (w). |
| All files | 644 | rw-r--r--: Owner can read/write. Group/Others can only read. No one gets execute (x). |
wp-config.php | 640 or 600 | rw-r-----: Owner can read/write. Group can read. "Others" can do nothing. This hides your DB pass. |
wp-content/uploads/ | 755 | Standard directory. This is where WordPress writes files, so the Owner needs w. |
Step 3: Apply (The Targeted Fix)
You already have the best commands for this from Part 1. You're not just running them blindly anymore; you're applying your plan.
Run these from [SITE_PATH]:
Bash
# 1. Apply the plan to directories
find [SITE_PATH] -type d -exec chmod 755 {} ;
# 2. Apply the plan to files
find [SITE_PATH] -type f -exec chmod 644 {} ;
# 3. Apply the special rule for wp-config
chmod 640 [SITE_PATH]/wp-config.php
Step 4: Verify (Trust, but Verify)
- Verify with Commands
First, run your audit commands again.
Bash
# Did it work for wp-config?
stat -c '%a %n' [SITE_PATH]/wp-config.php
Expected Output:
640 /var/www/html/wp-config.php
You can also run a "search for problems" command. This one finds any file or directory that is "world-writable" (i.e., has the "write" permission set for "Others").
Bash
# Find any world-writable paths (THIS SHOULD RETURN NOTHING)
find [SITE_PATH] -perm -0002 -printf '%m %pn'
If this command outputs anything, those files are a security risk.
- Verify with Your Eyes (The Real Test)
This is the most important step.
- **Open your website. Does it load?
- Log in to your admin dashboard.
- **Go to Media > Add New. Try to upload an image. (This tests
wpermission in youruploadsdirectory). - **Go to Plugins. Try to update a plugin. (This tests
wpermission for your plugin files).
If you can do all those things and your "Audit" commands look good, your job is done.
Part 5: Advanced chmod, Troubleshooting & Cheatsheet
Advanced chmod: Special Modes (The 4th Number)
Sometimes you'll see chmod used with four numbers instead of three, like chmod 2775. The first number is for "Special Modes."
For WordPress, you can safely ignore **SUID and Sticky Bit. They are for specialized Linux system tasks and are not used within a WordPress site's file structure.
However, the one special mode you might use is SGID.
- **What it is:SGID (Set Group ID), set with a
2(e.g.,chmod 2755). - **What it does: When you set SGID on a directory, any new file or directory created inside it will automatically "inherit" the group ownership from that parent directory.
- **Why a WordPress User Cares: This is useful if you have multiple users (like a developer and your web server) who both need to write files to the
uploadsfolder. - **Problem: Your
www-datauser uploads an image, and it's owned bywww-data:www-data. Then, you upload a file via SFTP, and it's owned bymyuser:myuser. This creates permission conflicts. - **Solution: You set the
wp-content/uploadsdirectory tochmod 2775. Now, all new files, no matter who creates them, are owned by thewww-datagroup. This stops the permission conflicts.
How to Apply SGID to Your uploads Folder (Optional):
Bash
# 1. Set the group for all files/dirs to 'www-data' (or your web group)
chgrp -R www-data [SITE_PATH]/wp-content/uploads
# 2. Apply 775 to directories (group can write)
find [SITE_PATH]/wp-content/uploads -type d -exec chmod 2775 {} ;
# 3. Apply 664 to files (group can write)
find [SITE_PATH]/wp-content/uploads -type f -exec chmod 664 {} ;
Note: This is an advanced setup. For most single-user-managed sites, the standard 755/644 permissions are perfectly fine.
WordPress Troubleshooting Matrix
If something is broken, check this table. **90% of permission issues are one of these.
| Symptom / Error Message | Likely Cause | The Fix |
|---|---|---|
| "Upload failed. Could not create directory" or "Unable to create directory..." | wp-content/uploads directory is not writable. | The directory (or its parent) is missing w (Write) or x (Execute) for the owner. Run: find [SITE_PATH]/wp-content/uploads -type d -exec chmod 755 {} ; |
| "Permission denied" when updating a plugin or theme. | WordPress can't write the new plugin files. | Your files are likely not owned by the web user, or your file permissions are too strict (e.g., 444). Run: find [SITE_PATH]/wp-content -type f -exec chmod 644 {} ; and find [SITE_PATH]/wp-content -type d -exec chmod 755 {} ; |
| Site is down, or you see a "403 Forbidden" error. | The server can't read your files. | You may have accidentally removed the "Read" permission. Or, more likely, you removed the x (Execute) permission from directories, so the server can't "enter" them to find index.php. Run the full quick-fix (Part 1). |
| Security scanner flags "World Writable Files." | You have files or directories set to 777 or 666. | This is a high-risk security flaw. Run: find [SITE_PATH] -perm -0002 -exec chmod o-w {} ; (This command finds and removes the "write" permission for "Others"). |
Best Practices & Final Review
- **DO use
755for directories. - **DO use
644for files. - **DO use
640or600forwp-config.php. - **DO use
findto apply permissions separately to files (type f) and directories (type d). - **DO check file ownership (
chown) first. Permissions won't matter if the wrong user (likeroot) owns all the files. - **DON'T ever use
chmod -R 777. This is the #1 way to get your site hacked. - **DON'T use
chmod -R 644(you'll break your directories) orchmod -R 755(you'll make your files executable).
chmod Cheatsheet
By the Numbers (Octal)
r(Read) = 4w(Write) = 2x(Execute) = 1
| Num | Permissions | Meaning |
|---|---|---|
| 7 | rwx (4+2+1) | Full permissions |
| 6 | rw- (4+2+0) | Read & Write |
| 5 | r-x (4+0+1) | Read & Execute |
| 4 | r-- (4+0+0) | Read Only |
| 0 | --- (0+0+0) | No permissions |
Standard WordPress Settings
755=rwxr-xr-xFor Directories644=rw-r--r--For Files640=rw-r-----Forwp-config.php
Key Commands
-
**The Full WP Fix:**Bash
find [SITE_PATH] -type d -exec chmod 755 {} ;find [SITE_PATH] -type f -exec chmod 644 {} ;chmod 640 [SITE_PATH]/wp-config.php -
**Check a File's Status:**Bash
stat -c '%a %U:%G %n' [file] -
**Find Dangerous Files (World-Writable):**Bash
find [SITE_PATH] -perm -0002 -print -
**Make a Script Executable:**Bash
chmod u+x my_script.sh