EACCES (Permission denied)

Fix 'Permission Denied' on Linux Files You Own

You see 'Permission denied' on a file you own? The kernel checks permissions before UID. Here's the real fix, from quick to deep.

Simple fix — 30 seconds

You're sitting there, ls -l shows -rw------- 1 root root 1024 Jan 1 12:00 secret.txt, and you own it. But cat secret.txt spits back Permission denied. What's actually happening here is the kernel's permission check. Even though you're the owner, the kernel looks at the file's permission bits — and if they don't include read for the owner, you're locked out.

The quickest fix: add read permission for the owner.

chmod u+r secret.txt

If it's a directory you can't enter, you also need execute:

chmod u+rx mydir

That's it. 30 seconds. If that works, you're done. No need to read further. But if you're still getting Permission denied after that, something else is blocking you.

Moderate fix — 5 minutes

So you ran chmod u+r and it silently succeeded, but cat still fails. The reason step 3 works is there are two more layers the kernel checks after file permissions: the immutable attribute and ACLs.

Immutable flag — chattr

If someone ran chattr +i secret.txt as root, that file is immutable. Even root can't modify it without clearing the flag first. Check with:

lsattr secret.txt

If you see ----i-------- in the output, that's the problem. Remove it with:

sudo chattr -i secret.txt

You need sudo here because changing attributes is a privileged operation. Once it's gone, your chmod will actually take effect.

ACL overrides

POSIX ACLs (Access Control Lists) can silently override the standard permission bits. Check with:

getfacl secret.txt

If you see something like user:root:--- where it should be r--, the ACL is blocking you. Fix it with:

setfacl -m u::r secret.txt

Or just remove all ACLs entirely:

setfacl -b secret.txt

Be careful — that wipes out any custom ACLs you might have set.

Advanced fix — 15+ minutes

If you've done both of the above and Permission denied still stares at you, you're dealing with one of two things: SELinux or AppArmor. These are mandatory access control (MAC) systems that run after the discretionary checks (ownership, permissions, ACLs). They can deny access even when Unix permissions say yes.

Check SELinux

First, confirm SELinux is even running:

getenforce

If it says Enforcing, SELinux is active. Now check the file's context against what the policy expects:

ls -Z secret.txt

You'll see something like unconfined_u:object_r:user_home_t:s0. If you moved this file from /tmp or another location, the context might be wrong. The real fix is to restore the default context for where the file lives:

restorecon -v secret.txt

If that doesn't work, you need to find out exactly what SELinux is blocking. Check the audit log:

sudo ausearch -m avc -ts recent

Or if you're on a system without auditd, use:

sudo cat /var/log/messages | grep AVC

The AVC denial message will tell you the exact source context, target context, and class. Sometimes the fix is as simple as changing the file's type to match what the policy expects. For example, if a web server needs to read it:

sudo semanage fcontext -a -t httpd_sys_content_t secret.txt
sudo restorecon -v secret.txt

Check AppArmor

If you're on Ubuntu or Debian, you're more likely dealing with AppArmor. Check its status:

sudo aa-status

Look for profiles that might apply to the process accessing the file. If you're blocked by an AppArmor profile, the audit log will show it:

sudo journalctl -k | grep -i apparmor

You'll see messages like DENIED with the profile name and path. The nuclear option is to disable the profile entirely, but don't do that in production. Instead, edit the profile in /etc/apparmor.d/ and add the appropriate allow rule for the file path, then reload:

sudo apparmor_parser -r /etc/apparmor.d/your-profile

One last check — filesystem mount options

I've seen this trip up people on shared hosts or Docker containers. Check the mount options of the filesystem:

mount | grep secret.txt

Or just run mount alone and look for noexec, nosuid, or nodev. While noexec doesn't block reads, it blocks execute — and if you're trying to run a binary, you'll see Permission denied. Rarely, a mount with ro (read-only) can confuse things if you're root. Check with cat /proc/mounts for the exact options.

Bottom line: When you own a file and still get denied, work through this checklist in order — permissions, then immutable flag, then ACLs, then MAC, then mount options. Nine times out of ten, it's the first one. But when it's not, knowing these deeper layers saves you from reinstalling your OS.

Related Errors in Linux & Unix
Systemd restart loop: 3 common causes and fixes Linux Graphical Target Won't Start – Fix in 3 Steps Uncaught EvalError: Refused to evaluate a string as JavaScript JS eval error on Google search? Here's the real fix Fix Kernel Panic: VFS Unable to Mount Root Filesystem

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.