1. File Permissions Are the Usual Suspect
Nine times out of ten, 'permission denied' on Linux is a classic file permission problem. You try to run a script or open a file, and the shell says no. The fix is almost always chmod or chown. I've seen new admins burn an hour on SELinux when the file was just mode 644.
Here's the drill. Check the current permissions with ls -l:
ls -l script.sh
-rw-r--r-- 1 root root 1234 Feb 12 10:00 script.shThe -rw-r--r-- means owner can read/write, everyone else can only read. No execute bit. To run it, add execute for the owner (or everyone if you prefer):
chmod 755 script.shNow it's -rwxr-xr-x and you can execute it. If the file is owned by another user, chown fixes that:
sudo chown youruser:yourgroup script.shThat's the 90% case. But what if permissions look fine and you still get the error? Read on.
2. SELinux or AppArmor Blocks You
You've checked permissions, they're fine, but the app still won't read or write. On CentOS, RHEL, Fedora, or any distro with SELinux enforcing, that's your next suspect. SELinux is a kernel-level security layer that can deny access even if file modes say 'ok'.
For example, you move a web file to /var/www/html and set 777, but Apache still can't read it. That's the classic SELinux context problem.
First, check if SELinux is enforcing:
getenforce
EnforcingIf it's Enforcing, look at the file context:
ls -Z /var/www/html/page.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/page.htmlIf the context is wrong, like user_home_t, fix it with:
sudo chcon -t httpd_sys_content_t /var/www/html/page.htmlThat changes the SELinux type so Apache can serve it. For a permanent fix, use semanage fcontext to set the default context, then restorecon.
If you're on Ubuntu or Debian, it's AppArmor instead. Check sudo aa-status to see if your app is confined. If it is, you'll need to adjust the profile in /etc/apparmor.d/. Don't just disable AppArmor — that's lazy and opens a big hole.
3. Mount Options: noexec, nodev, or nosuid
Sometimes the file is fine, but the partition it's on is mounted with options that restrict execution. You try to run a binary and get 'Permission denied' even though it's 755. The mount has noexec.
Check your mounts:
mount | grep /home
/dev/sdb1 on /home type ext4 (rw,noexec,nosuid,nodev)See the noexec flag? That means no binaries can run from there. This is common for /home on servers for security. To run a script there, either move it to a mount that allows exec (like /tmp or /usr/local/bin), or remount with exec:
sudo mount -o remount,exec /homeBut that only works for the current session. To make it permanent, edit /etc/fstab and remove noexec from the options column. Then reboot or remount. Be careful — /tmp is often noexec specifically to prevent malware; don't blindly remove it.
4. The File Is Locked by Another Process
Less common but annoying: you get 'permission denied' when you try to write to a file that another process has locked. This happens with databases, log files, or config files that a service is actively using.
For example, you try to edit /var/log/syslog and get 'permission denied' even though you're root. The syslog daemon has the file open. You don't need to edit it directly anyway.
Check who's holding the lock with lsof:
sudo lsof /var/log/syslog
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1234 syslog 1w REG 8,1 12345 54321 /var/log/syslogIf you must write to it, stop the service, make your change, then start it again. Don't force-kill the process unless you're sure it's safe.
Quick Reference Table
| Cause | Symptom | Fix |
|---|---|---|
| Wrong file permissions | Can't read/write/execute file | chmod or chown |
| SELinux or AppArmor | Access denied despite correct modes | Fix context or profile |
| Mount with noexec | Can't execute binaries on a partition | Remount with exec or move file |
| File locked by process | Can't write to a file in use | Stop service, edit, start |
That's the order I always check. Start with permissions, then check SELinux, then mounts, then locks. You'll solve most 'permission denied' errors in under five minutes if you follow that sequence. Don't skip steps — I've seen people reinstall a package to fix a permission error that was just a chmod away.