System administrator troubleshooting server permissions and access issues at workstation
Linux Troubleshooting
William  

Fix Permission Denied in Linux: Diagnose Before Chmod

Run strace on the failing command before you touch chmod. Permission denied on Linux is a syscall telling you exactly which access check failed, and the fix depends entirely on which one. Most "permission denied linux" answers on the internet reach straight for chmod 777 or sudo, which papers over the real cause: a missing directory execute bit, a noexec mount, an ACL, or an SELinux label. Read the error first, then fix the one thing that is actually wrong.

Last updated: 2026-07-21

What does permission denied actually mean in Linux?

It means a syscall returned EACCES. The kernel checked your user and group against the file's mode bits, the check failed, and the call bailed out with that error code. The message is precise, not vague. Something asked for read, write, or execute on a specific path and did not have it.

Linux permissions come down to three bits: read, write, and execute (r w x). Each is set separately for three audiences: the owner, the group, and everyone else. So a file can be readable by you and totally closed to everyone else, and that is normal. When a command dies with permission denied, one of those bits was missing for the identity the process ran as.

The part people miss is that directories use the same three bits with different meanings. On a directory, execute means "you may traverse into me," and read means "you may list my contents." You can own a file outright and still be blocked because a parent directory won't let you walk through it. Keep that in mind, because it explains half the confusing cases below.

Read the permissions with ls -l before you change anything

Run ls -l on the exact path and read the first field. It tells you everything before you guess.

-rwxr-xr-- 1 alice developers 4096 start.sh

Break that line down left to right:

  1. First character is the type. A dash means a regular file, d means a directory, l a symlink.
  2. Next three characters are the owner's bits: here rwx, so alice can read, write, and run it.
  3. Middle three are the group's bits: r-x, so the developers group can read and execute but not write.
  4. Last three are everyone else: r--, read only.
  5. Then the owner name and the group name: alice and developers.

Now run id and compare. If you are not alice and not in developers, you fall into "everyone else," and that last triplet decides what you can do. A missing x in your bracket is the single most common cause I see. Read the line, find your bracket, spot the missing bit. That tells you whether this is a mode problem, an ownership problem, or neither.

Fix it with chmod, not chmod 777

Once you know which bit is missing, add exactly that bit with chmod. The syntax is chmod [options] [mode] [File_name], and symbolic mode is clearer than octal for a targeted fix. It says who, what change, which bit.

CommandWhat it does
chmod u+x start.shAdds execute for the owner only
chmod g-w config.cfgRemoves write from the group
chmod o=r data.txtSets everyone else to read only
chmod 644 fileOwner read/write, group and others read

Reach for symbolic mode when you want to change one bit and leave the rest alone. Use octal when you are setting a known full state, like 644 for a config file or 755 for a script.

What I never do is chmod 777 to make the error go away. That grants write and execute to every user on the box, which is a security hole, and it usually does not even fix the problem, because the real block was a directory bit or a mount option that 777 never touched. If 777 "fixes" it, you got lucky and hid the cause. Add the one bit the error demanded, then confirm with ls -l again.

Change ownership with chown when the file belongs to someone else

Sometimes the bits are fine and the owner is wrong. A daemon or a sudo command created a file as root, and now your normal account can't write it no matter what mode it carries. That is a chown job, not a chmod one. The syntax is chown [OPTIONS] USER[:GROUP] FILE(s).

CommandEffect
chown alice data.logalice becomes the owner
chown bob:developers project/Sets owner to bob and group to developers
chown -R carol backups/Recurses through the whole tree

Use chown when the block is "this belongs to root and I need it to belong to me," not as a reflex. Be careful with the recursive -R flag. Point it at the wrong directory and you rewrite ownership on a whole tree, which is its own long night. Verify the owner field with ls -l afterward, every time.

When should you use sudo instead of touching permissions?

Use sudo when the file is supposed to be protected and you have a real reason to touch it. System-wide configuration files in /etc are owned by root on purpose. Editing /etc/fstab or /etc/ssh/sshd_config with sudo is correct. Loosening their mode so your normal user can write them is not.

The wrong turn is running everything through sudo to silence an error you never diagnosed. That hides a misconfiguration until it surfaces somewhere worse, usually as a file your service now can't read because you created it as root. Ask one question: is this file meant to be locked down, or did I misplace ownership? If it is genuinely a system file, sudo is the answer. If it is your own data blocked by a bit you set wrong, fix the bit.

Why do you get permission denied on Linux even as root?

Because root is not exempt from every check. People assume the root account walks through walls, then hit a permission denied linux error while running as root and lose an hour. Here are the cases root can't chmod away:

  • noexec mount. The filesystem was mounted with noexec, so nothing on it runs, root included. Common on /tmp and external drives. Run mount | grep <path> and look at the options.
  • Immutable attribute. Someone set the immutable flag with chattr +i. Even root can't write it until you clear it with chattr -i. Check with lsattr.
  • SELinux or AppArmor. A mandatory access control policy denied the action regardless of file mode. The Unix bits look perfect and the file still won't open.
  • NFS root-squash. On an NFS share, root on the client is mapped to the nobody user by the server. Your root is a stranger on that mount.

The lesson: when root gets denied, stop looking at mode bits. The block lives in the mount options, a file attribute, or a security policy. For the noexec and remount cases, my walkthrough on fixing stubborn disk mount problems covers where those options come from.

Why does ./start.sh say permission denied?

Because the file is missing its execute bit, and bash -bash: ./start.sh: permission denied is telling you that directly. Run through these in order:

  1. ls -l start.sh and check for x in your bracket. Missing? Run chmod u+x start.sh and try again.
  2. If the bit is set and it still fails, check the mount. mount | grep <dir> for noexec. A script on a noexec filesystem won't run even with x set.
  3. Read the shebang. head -1 start.sh should show something like #!/bin/bash. If the interpreter path is wrong or the file has Windows line endings, you can get a confusing denial. Run file start.sh to check for CRLF.
  4. Confirm you're calling the right path. ./start.sh runs the file here; a bare start.sh searches your $PATH and may find nothing or the wrong thing.

Nine times out of ten it is step one. But when the execute bit is clearly there and it still won't run, the mount or the shebang is your answer, and no amount of chmod will change that.

Permission denied on a folder you own

Owning a folder is not enough. To do anything inside it you need the execute bit on the directory itself, and on every parent directory in the path. Execute on a directory means "traverse into it." Without it, you can own a file two levels down and never reach it.

Read and execute do different jobs here. Read lets you list the names inside with ls. Execute lets you cd in and access files by name. A directory with read but not execute gives you the classic case where ls shows the file but touching it says permission denied. You can see the name and not walk to it.

Run namei -l /full/path/to/target. It walks the path one component at a time and prints the mode and owner at each level. Usually one parent directory is missing execute for your user, and that is the wall. Add it with chmod +x on that directory, not on the file you were staring at.

How do you diagnose permission denied that chmod and chown can't fix?

When the bits look right, the owner is you, and it still fails, stop guessing and watch the syscall. Run this first:

strace -f -e trace=open,openat,execve ./failing-command 2>&1 | grep -i denied

The line before EACCES names the exact path and operation that failed. That tells you what to check next instead of spraying chmod at everything. From there, work through the metadata the normal tools hide:

  1. ACLs. Run getfacl <file>. A plain ls -l doesn't show access control lists. An extra + at the end of the mode string in ls -l is your hint that one exists.
  2. File attributes. Run lsattr <file>. An i flag means immutable, an a means append-only. Clear with chattr if appropriate.
  3. SELinux. Run ausearch -m avc -ts recent or journalctl -t setroubleshoot. An AVC denial means the label is wrong, and you fix it with restorecon or chcon, not chmod.
  4. AppArmor. On Debian and Ubuntu, check dmesg | grep -i apparmor for a denial naming the profile.

If SELinux or AppArmor is the culprit, the strace will show EACCES on an operation the mode bits clearly permit. That mismatch is the tell. The strace tracing tool is the fastest way to catch it, and for the mandatory access control denials, my guide on reading Linux system logs shows where those messages land.

FAQ

Does chmod 777 ever make sense?

Almost never. There are narrow cases, like a scratch directory nobody sensitive can reach, but on any shared or networked box it hands write and execute to every account. If you think you need it, you have usually misdiagnosed the block. Find the one missing bit or the wrong owner instead.

How do I fix permission denied in the terminal on an external drive?

Check how it's mounted before changing any bits. Run mount | grep <mountpoint> and look for noexec or a filesystem like NTFS or FAT that ignores Unix permissions entirely. For those, ownership and mode are set by mount options at mount time, so you edit /etc/fstab with uid= and gid=, not chmod.

What's the difference between EACCES and EPERM?

EACCES means a normal permission check failed: your user lacks read, write, or execute on the path. EPERM means the operation is not permitted for a deeper reason, like a missing capability or an immutable attribute, and it often persists even as root. Reading which one strace prints saves you from chasing the wrong fix.

Why can I see a file with ls but not open it?

The containing directory has read but not execute. Read lets you list the names; execute lets you actually reach the files behind those names. Add execute to the directory with chmod +x, and check the whole path with namei -l in case a parent is the real blocker.

Do I need to reboot after fixing permissions?

No. Permission changes take effect immediately. If a running service still hits the old error, it's holding an open file descriptor or a cached path, so restart that service, not the machine. A reboot that "fixes" a permission error just means you changed something you didn't identify, and it will return.

Related on this blog