How to Fix Permission Denied Errors
Permission denied errors stop you from reading, writing, or executing files -- this guide covers every cause from file mode bits to SELinux contexts and Windows ACLs on Linux and Windows.
What You'll Learn
Why It Matters
Permission denied is one of the most common errors for developers deploying code, running scripts, or accessing logs. It can mean a missing execute bit, wrong owner, or a security module blocking access.
Real-World Use
When your CI/CD pipeline fails with "Permission denied" during a deploy, or your Docker container cannot write to a mounted volume, these fixes resolve the root cause.
Common Permission Denied Errors Table
| Error Message | Cause | Fix |
|---|---|---|
| bash: ./script.sh: Permission denied | Script lacks execute permission | chmod +x script.sh |
| Permission denied (publickey) | SSH key not authorized on remote server | Add public key to ~/.ssh/authorized_keys |
| EACCES: permission denied | npm global install without sudo on Linux | Fix npm prefix or use nvm |
| cannot open file: Permission denied | User lacks read access to the file | chmod 644 <file> or sudo |
| Operation not permitted | Filesystem flag or extended attribute | Check lsattr and remove immutable flag |
Step-by-Step Fixes
Fix 1: File Lacks Execute Permission
# Check current permissions
ls -la script.sh
# Add execute permission
chmod +x script.sh
# Run the script
./script.sh
Expected output:
-rwxr-xr-x 1 user user 42 Jun 22 10:00 script.sh
Script executed successfully
Fix 2: SSH Permission Denied (Publickey)
# Copy your public key to the remote server
ssh-copy-id user@192.168.1.100
# Or manually append the key
cat ~/.ssh/id_rsa.pub | ssh user@192.168.1.100 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Verify the connection
ssh -v user@192.168.1.100
Expected output:
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
Number of key(s) added: 1
Fix 3: npm Global Install EACCES
# Check current npm prefix
npm config get prefix
# Fix by changing npm's default directory
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# Alternatively, use nvm
nvm install node
Expected output:
/usr/local # before fix
/home/user/.npm-global # after fix
Fix 4: File Read Permission Denied
# Check file owner and permissions
ls -la /var/log/syslog
# Change file ownership
sudo chown user:user /var/log/syslog
# Or grant read permission to everyone
sudo chmod 644 /var/log/syslog
# Use sudo to read without changing
sudo tail /var/log/syslog
Expected output:
-rw-r--r-- 1 user user 12345 Jun 22 10:00 /var/log/syslog
Fix 5: Fix SELinux Context
# Check SELinux context
ls -Z /var/www/html/index.html
# Restore default context
sudo restorecon -v /var/www/html/index.html
# Change SELinux context manually
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
# Temporarily set SELinux to permissive for testing
sudo setenforce 0
Expected output:
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
Permission Denied Diagnosis Flowchart
flowchart TD
A[Permission Denied] --> B{Which OS?}
B -->|Linux/macOS| C[Check ls -la]
C --> D{Owner matches user?}
D -->|No| E[Run chown user:group]
D -->|Yes| F{Has read/write/execute bit?}
F -->|No| G[Run chmod to add bits]
F -->|Yes| H{Is SELinux enforcing?}
H -->|Yes| I[Check with ls -Z and restorecon]
B -->|Windows| J[Check icacls permissions]
J --> K[Run icacls /grant]
E --> L[Access Granted]
G --> L
I --> L
K --> L
Prevention Tips
- Use
chmod 755for directories andchmod 644for files as a secure baseline - Always use
ssh-copy-idinstead of manually copying keys - Install Node.js with nvm to avoid npm EACCES errors entirely
- Run
ls -labefore modifying any file to understand current permissions - Keep SELinux in enforcing mode and use
restoreconfor standard paths
Practice Questions
What do the three digits in
chmod 755mean? Answer: 7 = owner read+write+execute, 5 = group read+execute, 5 = others read+execute. Each digit is the sum of 4 (read), 2 (write), and 1 (execute).How do you find the SELinux context of a file? Answer: Use
ls -Z <file>to display the SELinux security context, including user, role, type, and sensitivity level.What does
ssh-copy-iddo? Answer: It appends your local public key to~/.ssh/authorized_keyson the remote server, setting the correct permissions automatically.Why does npm global install fail with EACCES on Linux? Answer: The default npm global directory is
/usr/local/lib/node_modules, which requires root access. Use a user-local prefix or nvm to avoid this.Challenge: Write a bash script that takes a file path as input, checks its current permissions and owner, and suggests the exact
chmodandchowncommands needed to make it readable and writable by the current user. Answer:#!/bin/bash file="$1" current_user=$(whoami) current_group=$(id -gn) perms=$(stat -c "%a" "$file") owner=$(stat -c "%U" "$file") if [ "$owner" != "$current_user" ]; then echo "Run: sudo chown $current_user:$current_group \"$file\"" fi if [ "$perms" -lt 644 ]; then echo "Run: chmod 644 \"$file\"" fi
Quick Reference
| Error | Diagnosis Command | Fix Command |
|---|---|---|
| Script no execute | ls -la script.sh |
chmod +x script.sh |
| SSH key denied | ssh -v user@host |
ssh-copy-id user@host |
| npm EACCES | npm config get prefix |
npm config set prefix ~/.npm-global |
| SELinux blocking | ls -Z file |
sudo restorecon -v file |
| Read denied | ls -la file |
sudo chmod 644 file |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro