Linux bash: Permission denied
Encountering "Permission denied" in Linux bash means your user lacks necessary file or directory permissions; this guide explains how to diagnose and fix it.
What This Error Means
When you see "Permission denied" in your Linux bash shell, it's the operating system telling you, quite directly, that you're attempting an action for which your current user account does not have the required access rights. This error is fundamental to Linux's security model, which is built on user and group permissions governing every file and directory in the system.
Fundamentally, every file and directory has three primary types of permissions:
* Read (r): Allows viewing the contents of a file or listing the contents of a directory.
* Write (w): Allows modifying or deleting a file, or creating/deleting files within a directory.
* Execute (x): Allows running a file as a program (if it's an executable script or binary) or traversing into a directory (meaning you can cd into it or access files inside it, even if you can't list its contents).
The "Permission denied" error indicates that one of these necessary permissions is missing for the user attempting the action.
Why It Happens
The Linux filesystem enforces a strict hierarchy of ownership and permissions. Each file and directory is owned by a specific user and belongs to a specific group. Permissions are then set for three categories: the owner of the file, the group that owns the file, and others (everyone else).
When you try to, for example, run a script, read a log file, or write to a configuration file, the system checks:
1. Who is trying to perform the action? (Your current user ID).
2. Who owns the target file/directory?
3. What group does the target file/directory belong to?
4. What permissions are set for the owner, group, and others on that target?
If your user ID is not the owner, not a member of the owning group, and the "others" permissions do not grant the required access, or if the "execute" bit isn't set on a script you're trying to run, then "Permission denied" is your inevitable result. In my experience, this is one of the most frequent hurdles for newcomers and a recurring check for seasoned engineers.
Common Causes
"Permission denied" is almost always a direct consequence of an improper permission setting. Here are the most common scenarios I've encountered:
- Missing Execute Permission on a Script: This is perhaps the most common. You download or create a script (
.sh, Python, Perl) and try to run it (e.g.,./myscript.sh), but it hasn't been marked as executable. The system sees it as just another text file. - Missing Read Permission on a File: Attempting to view the content of a file (
cat,less,more) for which your user or group lacks read access. This is common with sensitive configuration files or log files that are often restricted. - Missing Write Permission on a File or Directory: Trying to save changes to a file, create a new file, or delete an existing file in a directory where you don't have write access. This often happens in system directories (like
/usr/local/binor/etc) withoutsudo. - Incorrect Ownership: A file or directory might be owned by a different user (e.g.,
root,www-data) and your user isn't part of that group, nor do "others" have the necessary permissions. This frequently occurs when files are copied from a root-privileged operation or deployed by a different service user. - User Not in Correct Group: You might expect access to a file because it belongs to a certain group, but your user account hasn't been added to that group. This is common for shared resources like Docker sockets or specific hardware access groups.
- SELinux or AppArmor Restrictions: On systems with enhanced security modules like SELinux (e.g., CentOS, Fedora) or AppArmor (e.g., Ubuntu), even if standard file permissions appear correct, the security module might be preventing access based on its own policies. I've seen this in production when deploying services where the process context wasn't properly labelled, leading to unexpected access denials.
- Read-Only Filesystem: Less common for a direct "Permission denied" message (often yields "Read-only file system"), but if you're trying to write to a volume that has been mounted as read-only, you will be denied. This can happen during system recovery or when external media is mounted in a restricted fashion.
Step-by-Step Fix
Addressing "Permission denied" involves a systematic approach to identify the root cause and apply the correct fix.
-
Identify the Target and Action:
- What file or directory are you trying to access? (e.g.,
/home/ingrid/my_script.sh,/var/log/app.log,/opt/myapp/config/) - What action are you trying to perform? (execute, read, write, list directory contents?)
- What file or directory are you trying to access? (e.g.,
-
Check Permissions and Ownership:
- Use
ls -lon the target to view its permissions, owner, and group.
bash ls -l /path/to/problematic_file_or_directory - Example Output Interpretation:
-rwxr-xr-- 1 ingrid devgroup 1024 Jan 15 10:30 my_script.sh- The first character
-means it's a regular file (d for directory). rwxr-xr--defines permissions:rwx: Owner (ingrid) has read, write, and execute.r-x: Group (devgroup) has read and execute.r--: Others have only read access.
1: Number of hard links.ingrid: The owner of the file.devgroup: The group owner of the file.
- The first character
- Use
-
Determine Your Current User and Groups:
- Identify who you are currently logged in as and which groups you belong to.
bash whoami id -Gn - Compare
whoamioutput with the owner of the file, andid -Gnoutput with the group owner of the file. Are you the owner? Are you in the group?
- Identify who you are currently logged in as and which groups you belong to.
-
Assess Necessary Permissions:
- To execute a script: You (or your group/others, depending on the setting) need
xpermission on the file itself. - To read a file: You need
rpermission on the file. - To write to a file: You need
wpermission on the file. - To list directory contents: You need
rpermission on the directory. - To change into/traverse a directory: You need
xpermission on the directory. - To create/delete files in a directory: You need
wandxpermissions on the directory.
- To execute a script: You (or your group/others, depending on the setting) need
-
Apply the Fix (Using
chmodandchown):-
Changing Permissions (
chmod): This is the most common fix. Usechmodto add the necessary permissions.- To make a script executable for the owner:
bash chmod u+x /path/to/my_script.sh - To allow read/write for owner, read-only for group/others on a file:
bash chmod 644 /path/to/config.txt - To allow read/write/execute for owner, read/execute for group/others on a directory (common for web content directories):
bash chmod 755 /path/to/my_directory - To recursively apply permissions to files and directories within a directory: (Use with caution!)
bash chmod -R 755 /path/to/directory # For directories chmod -R 644 /path/to/directory # For files only (after finding them with find) - Note:
chmodcan use symbolic (e.g.,u+x) or octal (e.g.,755) modes. Octal mode combines read (4), write (2), and execute (1) values.755means:- Owner: 4+2+1 = 7 (rwx)
- Group: 4+0+1 = 5 (r-x)
- Others: 4+0+1 = 5 (r-x)
- To make a script executable for the owner:
-
Changing Ownership (
chown): If the file or directory is owned by the wrong user or group, you might need to change ownership. This typically requiressudo.- Change owner to
ingridfor a file:
bash sudo chown ingrid /path/to/some_file.txt - Change owner to
ingridand group todevgroupfor a directory:
bash sudo chown ingrid:devgroup /path/to/some_directory - Recursively change ownership for a directory and its contents: (Use with extreme caution!)
bash sudo chown -R ingrid:devgroup /path/to/project_root
- Change owner to
-
Adding User to a Group (
usermod): If your user needs access because of group permissions, ensure you're in that group. This requiressudoand a re-login for changes to take effect.
bash sudo usermod -aG devgroup ingrid # Then logout and log back in, or use 'newgrp devgroup' for immediate effect in current shell -
Using
sudofor Elevated Privileges: If you genuinely need to perform an action that requires root privileges (e.g., modifying system files), prepend your command withsudo. Always be judicious withsudo.
bash sudo nano /etc/nginx/nginx.conf
-
-
Advanced Checks (SELinux/AppArmor):
- If standard permissions are correct, but you're still getting denied, check your security modules.
- SELinux: Use
sestatusto see if it's enabled.getenforceshows enforcing/permissive mode.audit.logoften contains AVC denials (grep "AVC" /var/log/audit/audit.log). Temporarily set to permissive (sudo setenforce 0) to confirm if it's the issue (revert withsudo setenforce 1). - AppArmor: Use
aa-statusto check status. Review/var/log/syslogordmesgfor AppArmor denials.
Code Examples
Here are some concise, copy-paste ready examples for common permission scenarios:
1. Make a script executable:
# Verify current permissions (missing 'x' for user/group/others)
ls -l my_script.sh
# Output: -rw-r--r-- 1 user group 100 Jan 1 09:00 my_script.sh
# Add execute permission for the owner
chmod u+x my_script.sh
# Verify updated permissions
ls -l my_script.sh
# Output: -rwxr--r-- 1 user group 100 Jan 1 09:00 my_script.sh
2. Grant read/write access to a config file for the owner only:
# Secure a config file
chmod 600 production_config.ini
# Verify
ls -l production_config.ini
# Output: -rw------- 1 user group 250 Jan 1 09:05 production_config.ini
3. Set standard directory permissions (owner rwx, group rx, others rx):
# For a web root directory, for example
chmod 755 /var/www/html/mysite
# Verify
ls -ld /var/www/html/mysite
# Output: drwxr-xr-x 2 user group 4096 Jan 1 09:10 /var/www/html/mysite
4. Change file ownership to a specific user and group (requires sudo):
# Assume a file was created by root and needs to be owned by 'appuser' and 'appgroup'
sudo chown appuser:appgroup /opt/myapp/data/shared.txt
# Verify
ls -l /opt/myapp/data/shared.txt
# Output: -rw-r--r-- 1 appuser appgroup 1200 Jan 1 09:15 shared.txt
5. Add your user to an existing group (e.g., docker group) and verify (requires sudo and re-login):
# Add current user to the 'docker' group
sudo usermod -aG docker $(whoami)
# Log out and log back in, then verify group membership
id -Gn
# Output should now include 'docker'
Environment-Specific Notes
Permission issues can manifest differently or have unique considerations depending on your environment.
-
Cloud Instances (AWS EC2, GCP Compute Engine, Azure VMs):
- Default Users: Often, cloud instances come with default users (e.g.,
ec2-useron Amazon Linux,ubuntuon Ubuntu AMIs,centoson CentOS images). These users typically havesudoprivileges, but file ownership created by installation scripts (which often run asroot) can cause issues. - SSH Key Permissions: Your SSH private key itself needs
chmod 400permissions. If not,sshwill deny access with a "Permission denied (publickey)" error. This isn't a filesystem permission on the remote server but on your local machine. - IAM Roles/Service Accounts: While not direct filesystem permissions, if a service running on a VM (e.g., an application trying to write to S3) experiences "Access Denied," it's often an IAM permission issue, not a local filesystem one.
- Root Filesystem: I've seen situations where the root filesystem gets mounted read-only due to disk corruption or system health checks, leading to write errors across the board.
- Default Users: Often, cloud instances come with default users (e.g.,
-
Docker Containers:
- Inside the Container: Permissions are handled normally inside the container based on the container's user. By default, processes run as
rootinside the container unless specified by theUSERdirective in the Dockerfile. - Volume Mounts (
-v): This is a frequent pain point. When you mount a host directory into a container, the host's permissions and ownership are retained. If the user inside the container doesn't have the necessary UID/GID to access the mounted directory from the host, you'll get "Permission denied". Often, aligning UIDs/GIDs or running the container asroot(not recommended for production) or a specific user (docker run --user <UID>:<GID>) is necessary. - Docker Socket: Accessing the Docker daemon from within a container (Docker-in-Docker) or from your user requires your user to be in the
dockergroup, which provides write access to/var/run/docker.sock.
- Inside the Container: Permissions are handled normally inside the container based on the container's user. By default, processes run as
-
Local Development Environments:
umask: Your shell'sumasksetting determines the default permissions for newly created files and directories. A restrictiveumask(e.g.,077) can mean files you create aren't accessible to others by default, leading to issues in collaborative projects.- External Drives/NFS: External USB drives, network shares (NFS, SMB), or cloud sync folders often have their own permission nuances.
noexecmounts can prevent execution, and ownership mapping can differ, leading to permission problems that aren't solvable withchmod/chownwithout remounting or adjusting server-side settings. I've often seen this when using shared development environments, where one user creates files and others can't modify them due toumaskor misconfigured group access.
Frequently Asked Questions
-
Q: Why does
sudonot always fix "Permission denied"?
A: Whilesudogrants root privileges, it can't bypass all restrictions. Common reasonssudomight still fail include:- Read-only filesystem: The underlying filesystem is mounted as read-only.
sudocannot change this. - SELinux/AppArmor: These security modules can block even root-level access based on their policies.
- Immutable files: Files marked with the
chattr +iattribute cannot be modified or deleted, even by root, without removing the attribute first (chattr -i).
- Read-only filesystem: The underlying filesystem is mounted as read-only.
-
Q: What is the difference between
chmod 777andchmod 755?
A:chmod 777grants read, write, and execute permissions to everyone (owner, group, and others). This is highly insecure for most files and directories and should be avoided unless absolutely necessary for very specific, non-sensitive temporary files.chmod 755grants read, write, and execute to the owner, and read and execute to the group and others. This is a common and safer permission set for directories and executable scripts that need to be accessible (but not modifiable by) others. -
Q: Can "Permission denied" happen for directories?
A: Yes, absolutely. If you lack thex(execute) permission on a directory, you won't be able tocdinto it or access its contents, resulting in "Permission denied." If you lackr(read) permission, you can't list its contents (ls). If you lackw(write) permission, you can't create or delete files within it. -
Q: My script has execute permission but still fails with "Permission denied" when I run
./script.sh?
A: Check two things:- Shebang: Ensure the script has a correct "shebang" line at the very top (e.g.,
#!/bin/bashor#!/usr/bin/env python3). If this is missing or incorrect, the kernel doesn't know how to execute the file. - Directory Permissions: Make sure the directory containing the script has execute (
x) permission for your user, allowing you to traverse into it.
- Shebang: Ensure the script has a correct "shebang" line at the very top (e.g.,