How to Fix “Permission Denied” Errors on Linux: chmod and chown Explained

Overview

The Permission Denied error is one of the most common things you’ll run into on a Linux server. It means the user or process trying to access a file doesn’t have the rights to do so — either because the file’s ownership is wrong, the permission bits aren’t set correctly, or both. Linux permissions control everything: who can read a file, write to it, or execute it.

On a web hosting server, this usually surfaces when you upload files via FTP, restore a backup, run a PHP script, or switch between users. The web server process (typically www-data, apache, or nobody depending on your stack) can’t access your files because they’re owned by a different user. If you’re on a VPS SSD Hosting plan or a dedicated server, you’ll have the root access needed to fix these properly — shared hosting users may need to work within cPanel’s File Manager or contact support.

This article covers how to read Linux file permissions, how to fix ownership with chown, how to set correct permission modes with chmod, and what to do when the obvious fix doesn’t work.

Prerequisites

  • SSH access to your server (root or sudo user), or access to cPanel File Manager
  • Basic familiarity with a terminal — you don’t need to be an expert, but you’ll need to run commands
  • Knowledge of which user your web server runs as (common values: www-data on Ubuntu/Debian, apache on CentOS/AlmaLinux, nobody on some cPanel stacks)
  • The path to the file or directory causing the error

Step 1 — Read the Current Permissions

Before changing anything, check what the permissions actually are. Run ls -la on the file or directory in question. The -a flag shows hidden files, and -l gives the long format with permissions visible.

ls -la /var/www/html/mysite/

You’ll see output like this:

drwxr-xr-x  3 root     root     4096 Jan 10 09:15 mysite
-rw-r--r--  1 root     root     1234 Jan 10 09:15 index.php
-rw-------  1 root     root      512 Jan 10 09:15 config.php

Here’s how to read those permission strings:

  • The first character is the type: d = directory, - = file, l = symlink
  • The next 9 characters are three groups of three: owner, group, others
  • Each group: r = read, w = write, x = execute (or - if not set)
  • The two columns after the permissions show the owner and group

In the example above, config.php is set to rw-------, meaning only root can read or write it. If your web server process is running as www-data, it’ll get a Permission Denied error trying to read that file.

Step 2 — Fix Ownership with chown

chown changes who owns a file or directory. This is often the actual fix when your web server can’t access files you uploaded as a different user.

To change the owner of a single file:

sudo chown www-data:www-data /var/www/html/mysite/config.php

To change ownership recursively for an entire directory (use with care — see the warning below):

sudo chown -R www-data:www-data /var/www/html/mysite/

The format is chown user:group. You can omit the group if you only need to change the owner: chown www-data file.php.

📝 Note: On cPanel servers, files are typically owned by the cPanel account username (e.g., myaccount) rather than www-data. Check your actual username with whoami and use that instead.

Warning: Running chown -R root:root /var/www/ recursively as root will break your site — your web server won’t be able to read anything. Always double-check the user and path before using -R.

Step 3 — Fix Permission Bits with chmod

Even with correct ownership, wrong permission bits will still cause denials. chmod sets what the owner, group, and others are allowed to do with a file.

For most web hosting scenarios, you want:

  • Files: 644 — owner can read/write, group and others can read only
  • Directories: 755 — owner can read/write/enter, group and others can read and enter
  • Scripts that need to execute: 755
  • Sensitive config files (e.g., wp-config.php): 640 or 600

To set permissions on a single file:

sudo chmod 644 /var/www/html/mysite/index.php

To fix an entire site’s files and directories at once — this is something I use regularly after restoring backups:

# Set all files to 644
find /var/www/html/mysite -type f -exec chmod 644 {} ;

# Set all directories to 755
find /var/www/html/mysite -type d -exec chmod 755 {} ;

📝 Note: The numbers in chmod are octal. 644 means: owner gets 4+2=6 (read+write), group gets 4 (read), others get 4 (read). You don’t need to memorise the math, but knowing 7=full, 6=read/write, 5=read/execute, 4=read only covers 95% of cases.

Warning: Don’t set directories or files to 777 unless you fully understand the implications. It grants write access to every user on the server, which is a serious security risk — especially on shared hosting environments.

Step 4 — Verify the Fix

After making changes, recheck with ls -la and test your application. If it’s a web app, reload the page. If it’s a script, run it again.

ls -la /var/www/html/mysite/config.php

Expected output (for a file owned by www-data with 640 permissions):

-rw-r-----  1 www-data www-data  512 Jan 10 09:15 config.php

If you’re still seeing permission errors after fixing ownership and chmod, jump to the troubleshooting section below — there are a few less obvious causes.

Common Issues & Troubleshooting

Still Getting “Permission Denied” After Running chmod

Cause: The file might be on a filesystem mounted with the noexec or nosuid option, or there’s an SELinux/AppArmor policy blocking access regardless of standard Unix permissions.

Fix: Check mount options with cat /proc/mounts. For SELinux, check with sestatus and look at audit logs in /var/log/audit/audit.log. For AppArmor, check aa-status. These security layers operate independently of standard Linux permissions — chmod alone won’t help.

PHP Script Returns 500 Error or “open_basedir restriction” Instead of Running

Cause: PHP’s open_basedir directive restricts which directories PHP can access, regardless of file system permissions. This is separate from Linux permissions entirely.

Fix: Check your PHP configuration — either in php.ini, a .htaccess directive, or in WHM under Service Configuration > PHP Configuration Editor. Make sure your file path falls within the allowed directories.

“Operation Not Permitted” When Running chown as a Non-Root User

Cause: On Linux, only root can change a file’s owner to another user. If you’re running chown without sudo and you’re not root, you’ll get this error. Regular users can only change group ownership to a group they’re already a member of.

Fix: Prefix with sudo, or switch to root with sudo -i. If you’re on shared hosting without root access, use cPanel’s File Manager — it runs permission changes as root on your behalf.

WordPress Can’t Write to wp-content After Uploading Files via FTP

Cause: FTP uploads create files owned by your FTP user, not the web server user. WordPress needs write access to wp-content/uploads to handle media uploads.

Fix: Either change ownership of wp-content to the web server user (e.g., www-data), or set it to 775 and add your FTP user to the web server’s group. I’d recommend the ownership approach on any server you control:

sudo chown -R www-data:www-data /var/www/html/wordpress/wp-content/
sudo chmod -R 755 /var/www/html/wordpress/wp-content/
sudo chmod -R 775 /var/www/html/wordpress/wp-content/uploads/

Permissions Look Correct but SSH Key Login Fails with “Permission Denied”

Cause: SSH is extremely strict about permissions on your ~/.ssh directory and authorized_keys file. If these are group- or world-writable, SSH will silently reject the key — this trips up a lot of people because the permissions look fine at a glance.

Fix: Set the exact permissions SSH requires:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

FAQ

Frequently Asked Questions

What's the difference between chmod and chown?

chown changes who owns a file — the user and group assigned to it. chmod changes what that owner (and everyone else) is allowed to do with the file, like read, write, or execute it. When you get a Permission Denied error, you usually need to check both: the right user needs to own the file, and the permission bits need to allow that user to access it.

Is it safe to use chmod 777 on my web files?

No, and I’d strongly advise against it. chmod 777 gives every user on the server full read, write, and execute access to that file. On a shared hosting environment especially, that’s a genuine security risk — other accounts could modify or read your files. Use 644 for files and 755 for directories in almost all web hosting situations.

How do I find all files with wrong permissions on my Linux server?

You can use the find command to locate files that don’t match expected permissions. For example, to find files that are world-writable: find /var/www/html -type f -perm -o+w. To find files that are readable by everyone but shouldn’t be (like config files), check for 644 or higher where you expected 640 or 600.

Can I fix file permissions from cPanel without SSH?

Yes. In cPanel, go to Files > File Manager, navigate to the file or directory, right-click it, and select Change Permissions. You’ll see checkboxes for read, write, and execute for owner, group, and world. It’s less flexible than the command line but works fine for one-off fixes. For bulk changes across a whole site, SSH is much faster.

Why do my file permissions reset after I fix them?

This usually means something is overwriting them — a deployment script, a CMS auto-update process, or a backup restore. Check whether you have any automated processes running (cron jobs, CI/CD pipelines, cPanel backup restores) that might be re-uploading or extracting files. Fixing the permissions in that script or process is the permanent solution, not manually resetting them each time.

SHARE THIS ARTICLE

Need help with your hosting?

Host & Tech provides 24/7 support for all VPS, dedicated, and shared hosting customers.

Scroll to Top