Skip to main content

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.

777 gives 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.

777 gives 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

  1. **Owner (u): The user who owns the file (e.g., your personal user account, like myuser).
  2. **Group (g): A group of users. On a server, this is often the web server itself (e.g., www-data, apache, or lshttp).
  3. **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.

PermissionFor 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 755 and 644 actually 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) = 4
  • w (Write) = 2
  • x (Execute) = 1
  • (No permission) = 0

You just add the numbers together for each of the three groups (Owner, Group, Others).

NumberPermissionsWhat it means
7rwx (4+2+1)Full permissions.
6rw- (4+2+0)Read and Write.
5r-x (4+0+1)Read and Execute.
4r-- (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.php is not writable by the group:Bash

    chmod 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]).

  1. 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.

  1. 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:

  • 644 or 666: 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 / TargetRecommended ModeRationale (The "Why")
All directories755rwxr-xr-x: Owner can do anything. Group/Others can enter (x) and list (r) but not write (w).
All files644rw-r--r--: Owner can read/write. Group/Others can only read. No one gets execute (x).
wp-config.php640 or 600rw-r-----: Owner can read/write. Group can read. "Others" can do nothing. This hides your DB pass.
wp-content/uploads/755Standard 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)

  1. 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.

  1. 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 w permission in your uploads directory).
  • **Go to Plugins. Try to update a plugin. (This tests w permission 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 uploads folder.
  • **Problem: Your www-data user uploads an image, and it's owned by www-data:www-data. Then, you upload a file via SFTP, and it's owned by myuser:myuser. This creates permission conflicts.
  • **Solution: You set the wp-content/uploads directory to chmod 2775. Now, all new files, no matter who creates them, are owned by the www-data group. 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 MessageLikely CauseThe 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 755 for directories.
  • **DO use 644 for files.
  • **DO use 640 or 600 for wp-config.php.
  • **DO use find to 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 (like root) 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) or chmod -R 755 (you'll make your files executable).

chmod Cheatsheet

By the Numbers (Octal)

  • r (Read) = 4
  • w (Write) = 2
  • x (Execute) = 1
NumPermissionsMeaning
7rwx (4+2+1)Full permissions
6rw- (4+2+0)Read & Write
5r-x (4+0+1)Read & Execute
4r-- (4+0+0)Read Only
0--- (0+0+0)No permissions

Standard WordPress Settings

  • 755 = rwxr-xr-x For Directories
  • 644 = rw-r--r-- For Files
  • 640 = rw-r----- For wp-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