News
New Serverspace Data Center in Uzbekistan: Tashkent Located
Serverspace Black Friday
AC
May 7 2026
Updated May 7 2026

Permission Denied on Linux: How to Fix the Error and Restore Access

Linux

Almost every Linux administrator has hit the "Permission denied" error at some point. We try to run a script, open a file, enter a directory, or connect via SSH, and the terminal returns the block message. The most common reaction is to throw a chmod 777 on top and move on, which fixes the symptom while opening security holes in the system.

In this guide we will show how to diagnose the actual cause of the error, identify which layer is blocking access, and apply the minimal correction needed. We cover the POSIX model, the proper use of chmod and chown, common scenarios like SSH keys and web directories, plus additional layers such as SELinux and extended attributes.

For practical exercises, a disposable server is a good idea. A VPS Linux on Serverspace works well for testing the commands in an isolated environment. The examples work the same way on Ubuntu, Debian, AlmaLinux, and Rocky.

What the "Permission denied" error means

The message appears when the Linux kernel refuses an operation because the current user lacks sufficient rights over the file or directory involved. The text is almost always the same, while the causes vary considerably.

The most frequent contexts include trying to execute a script without the execute bit, reading a file owned by another user, writing to system directories such as /etc or /var/www, accessing a folder via cd without the x bit, and SSH authentication with keys whose permissions are too open.

Before applying any fix, it helps to know that Linux checks access in three layers. The first is classic POSIX permissions (rwx for owner, group, and others). The second is extended ACLs, which allow finer rules for specific users and groups. The third is mandatory security modules: SELinux on RHEL and derivatives, AppArmor on Ubuntu and Debian.

Terminology: how Linux organizes permissions

Access control is based on three subject categories and three operation types. The categories are: file owner (user, u), file group (group, g), and other system users (others, o). Each file has a single owner and a single associated group, set when the file is created.

The operation types are read (r), write (w), and execute (x). For files, the meaning is direct. For directories there is an important subtlety: read lists the contents, write lets us create and remove files inside, and execute lets us traverse the directory, meaning cd into it and reach files by full path.

The output of ls -l shows this model in action:

-rwxr-xr-- 1 maria devs 2048 Mar 10 14:20 deploy.sh

The first character indicates the type (- for regular file, d for directory, l for symbolic link). The next nine characters form three triplets, one per category: rwx for the owner, r-x for the group, r-- for others.

There are two ways to set permissions with chmod. The symbolic form uses letters and operators (chmod u+x script.sh adds execution for the owner). The octal form sums the values 4 (r), 2 (w), and 1 (x) per category, producing three digits. The most common combinations in daily work:

Octal Symbolic Typical use What it grants
644 rw-r--r-- Text files, configs Owner edits, others read
755 rwxr-xr-x Directories, public scripts Everyone can navigate and execute
700 rwx------ ~/.ssh, private data Owner-only access
600 rw------- SSH private keys, .env files Owner reads and writes only
775 rwxrwxr-x Shared upload folder Group writes, others read

Memorizing these five combinations covers most practical situations. Anything else can be built from them with small variations.

How the permission system works

When a process tries to access a file, the kernel runs through a sequence of checks. First it compares the process UID with the file owner's UID. If they match, owner bits apply. Otherwise, it checks whether any of the user's groups matches the file's group and applies group bits. If neither condition holds, the others triplet applies.

This flow has important implications. For deletion, the write permission on the parent directory matters more than the permission on the file itself. That is why we can sometimes remove read-only files without obstacles, as long as we have write access on the containing directory.

Another implication involves the execute bit on directories. If /home/maria/projects has no x bit for the current user, no file inside can be accessed, even with open permissions. The entire path to the file must be traversable.

Finally, it is worth knowing about umask. When we create a new file, the system starts from 666 (files) or 777 (directories) and subtracts the umask. The default of 022 results in 644 for files and 755 for directories.

Practical scenarios where the error appears

Shell script without execute permission

We create a script, write a few lines, and try to run it:

$ ./deploy.sh

bash: ./deploy.sh: Permission denied

The cause is that the file was created without the x bit. The fix is to add execution for the owner:

chmod u+x deploy.sh

./deploy.sh

If the script should run for all users, we can use chmod 755. For personal use, chmod 700 keeps the script private.

SSH key with permissions too open

When connecting to a server:

Permissions 0644 for '~/.ssh/id_rsa' are too open.

It is required that your private key files are NOT accessible by others.

This behavior comes from the StrictModes yes parameter, enabled by default in sshd_config. The server refuses any key that can be read by other users on the client machine. The fix requires closed permissions on the key and the directory:

chmod 700 ~/.ssh

chmod 600 ~/.ssh/id_rsa

chmod 644 ~/.ssh/id_rsa.pub

chmod 600 ~/.ssh/authorized_keys

Writing to a system directory

Trying to create a file inside /etc or /var/www as a regular user causes an immediate block. The fix depends on intent. For one-off changes to system files, sudo solves it. For web directories where an application writes regularly, the correct path is to adjust ownership:

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

sudo find /var/www/html -type d -exec chmod 755 {} \;

sudo find /var/www/html -type f -exec chmod 644 {} \;

Accessing another user's files

If maria needs to read files created by joao, there are two clean options. The first is to add maria to joao's group and ensure read access on the group:

sudo usermod -aG joao maria

chmod g+r /home/joao/report.txt

The second uses ACLs for a specific rule without touching groups:

sudo setfacl -m u:maria:r /home/joao/report.txt

Read-only filesystem or immutable attribute

In some cases, chmod itself returns Permission denied, even for root. The two most likely causes are: the filesystem was mounted with the ro option, or the file received the i (immutable) attribute via chattr. To diagnose:

mount | grep " on / "

lsattr file

If the file has the i attribute, we remove it with sudo chattr -i file. If the partition is mounted read-only, we remount it with write access or adjust /etc/fstab.

Step-by-step instruction: diagnosis and fix

Whenever a Permission denied appears, we recommend following this sequence. It leads to the right diagnosis without guessing.

Step 1. Identify owner, group, and permissions

ls -l file

ls -ld directory

id

groups

The ls -l command shows the owner, group, and rwx bits. The id command reveals the current user's UID, primary GID, and supplementary groups. Comparing the two, we discover which triplet access is being evaluated against. For even more detailed information, stat provides everything, including timestamps and inode number:

stat file

Step 2. Adjust permissions with chmod

With the cause identified, we adjust permissions. The symbolic form is convenient for targeted changes:

chmod u+x script.sh

chmod g-w file.txt

chmod o=r file.txt

The octal form is better when setting a complete set at once:

chmod 644 config.yaml

chmod 755 deploy.sh

chmod 600 ~/.ssh/id_rsa

chmod 700 ~/.ssh

For recursive adjustments on directory trees, avoid chmod -R with a single value. Use find to separate files and directories:

find /path -type d -exec chmod 755 {} \;

find /path -type f -exec chmod 644 {} \;

Step 3. Fix ownership with chown

When the problem is the file's owner or group, chown solves it:

sudo chown maria file.txt

sudo chown maria:devs file.txt

sudo chown :devs file.txt

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

The user:group syntax covers both adjustments in a single operation. The -R flag applies recursively to directories and their contents.

Step 4. Use sudo when it makes sense

sudo is the right tool for operations on system files (/etc, /var/log, /usr) and for starting services that need privileges. For files inside /home or your own projects, prefer fixing ownership with chown over running everything as root, which avoids creating root-owned files in your personal directory.

Step 5. Check additional layers

If POSIX permissions are correct and the error persists, it is time to look at the extra layers. To check ACLs:

getfacl file

If there are entries denying access, adjust with setfacl or remove them with setfacl -b.

To check SELinux on RHEL, AlmaLinux, or Rocky systems:

getenforce

sudo ausearch -m avc -ts recent

If getenforce returns Enforcing and ausearch shows blocks, the SELinux policy is denying access. The fix depends on context, possibly involving restorecon, chcon, or boolean adjustments with setsebool.

To check AppArmor on Ubuntu and Debian, use sudo aa-status. If an active profile restricts the application, the logs in /var/log/syslog or /var/log/audit/audit.log show the denial.

Common mistakes when fixing permissions

We list the slips that cause the most problems and how to avoid them.

Applying chmod 777 on everything is the most tempting fix and the worst idea. It grants read, write, and execute to any user on the system. On exposed servers, it is a recipe for compromise. Identify the specific user or group that needs access and grant only what is necessary.

Using chmod -R 755 on mixed trees adds the x bit unnecessarily on regular files. Use find with -type d and -type f to separate files and directories.

Forgetting the x bit on the parent directory causes failures even with open permissions on the file. Check the entire path with ls -ld at every level.

Reversing the order of chmod and chown in provisioning scripts (Dockerfiles, Ansible) can result in incorrect permissions if chown alters suid and sgid bits. The safe order is chown first, then chmod.

Ignoring SELinux on CentOS, AlmaLinux, and Rocky is a common time-waster. Always run getenforce and ausearch when POSIX adjustments do not fix the issue.

Using sudo where ownership should be fixed creates root-owned files in the wrong places. If an application needs to write to /var/www, set the owner to www-data and let the application run as that user.

Conclusion

Permission denied is less an obstacle and more a clear signal that the system is doing its job. The right approach is to understand which layer caused the block and fix the exact spot.

With practice, decoding a Permission denied message becomes a matter of seconds. The sequence works in any scenario: ls -l and id for diagnosis, chmod to adjust bits, chown to fix ownership, sudo only when it makes sense, and verification of ACLs and SELinux when the rest looks ok.

Vote:
5 out of 5
Аverage rating : 5
Rated by: 1
1101 CT Amsterdam The Netherlands, Herikerbergweg 292
+31 20 262-58-98
700 300
ITGLOBAL.COM NL
700 300
We use cookies to make your experience on the Serverspace better. By continuing to browse our website, you agree to our
Use of Cookies and Privacy Policy.