Cause 1: The file or directory lacks execute permission (most common)
You try to run a script or access a directory and get bash: ./script.sh: Permission denied. Nine times out of ten, the file doesn't have the execute bit set. Permissions on Linux are a simple math: read (4), write (2), execute (1). You add them up for owner, group, and others.
For a script, you need at least execute (1) for yourself. For a directory, you need execute to traverse into it—even if you have read permission, without execute you can't cd into it or list its contents.
How to check and fix
- Run
ls -l /path/to/file. Look at the first column, like-rw-r--r--. Noxmeans no execute permission. - To add execute for everyone, run:
After you run this,chmod +x /path/to/filels -lwill show-rwxr-xr-x. - If it's a directory, you might also need read and execute for all users. A safe bet is
chmod 755 /path/to/dir—that gives read and execute to everyone, write to the owner only.
Now try your command again. If you get a different error or it runs, you're done.
Cause 2: The file is owned by another user or group
Say you copied a file from a USB stick or a colleague sent it over. The owner might be root or someone else's UID. You have read/write permission on paper, but the system says Permission denied because you're not the owner and you lack group access.
I've seen this happen constantly with files extracted from a tar archive created on another machine. The original owner's UID doesn't exist on your system, so it shows up as a number or nobody.
How to check and fix
- Run
ls -l /path/to/file. The third and fourth columns show the owner and group. If it'srootand you're not root, that's your problem. - Change the owner to your user. You need sudo for this:
Use the commandsudo chown yourusername:yourusername /path/to/fileidto find your username and group if you're not sure. - For a whole directory tree, add
-Rto apply recursively:
After this,sudo chown -R yourusername:yourusername /path/to/dirls -lshould show your username as the owner.
If you don't have sudo, you're stuck—ask the admin to change it for you.
Cause 3: SELinux is blocking access (especially on RHEL/Fedora/CentOS)
On systems with SELinux in enforcing mode, you can have perfect Unix permissions and still get Permission denied. SELinux is a mandatory access control layer that goes beyond file permissions. It labels processes and files, and if the policy doesn't allow the interaction, you're locked out.
Classic trigger: you move your web directory to /home/user/www and Apache can't read it. Or you try to access an NFS mount that's labeled default_t when it should be httpd_sys_content_t.
How to check and fix
- Check if SELinux is on:
getenforce. If it returnsEnforcing, move to the next step. - Check for denials in the audit log:
You'll see lines withsudo ausearch -m avc -ts recentavc: deniedmessages. If nothing shows, your issue isn't SELinux. - To fix the specific label, change the context. For a web file, do:
For an NFS mount, you might needsudo chcon -t httpd_sys_content_t /path/to/filenfs_tinstead. Usels -Zto see current labels. - If you're in a pinch and just want SELinux off temporarily, set it permissive:
That gets you running, but don't leave it disabled for production—you're removing a safety net.sudo setenforce 0
Restart your service and test. If it works, you can make the label permanent with semanage fcontext—that's a deeper dive, but the chcon fix is fine for quick repairs.
Quick-reference summary
| Cause | Check | Fix |
|---|---|---|
| No execute permission | ls -l — missing x | chmod +x file |
| Wrong ownership | ls -l — owner is root/nobody | sudo chown user:group file |
| SELinux block | ausearch -m avc — denied messages | sudo chcon -t httpd_sys_content_t file |
These three cover 95% of the Permission Denied errors I've fixed. When in doubt, start with ls -l—it tells you more than any other command.