Skip to content

How to Fix Permission Denied Errors

DodaTech Updated 2026-06-22 4 min read

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 755 for directories and chmod 644 for files as a secure baseline
  • Always use ssh-copy-id instead of manually copying keys
  • Install Node.js with nvm to avoid npm EACCES errors entirely
  • Run ls -la before modifying any file to understand current permissions
  • Keep SELinux in enforcing mode and use restorecon for standard paths

Practice Questions

  1. What do the three digits in chmod 755 mean? 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).

  2. 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.

  3. What does ssh-copy-id do? Answer: It appends your local public key to ~/.ssh/authorized_keys on the remote server, setting the correct permissions automatically.

  4. 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.

  5. Challenge: Write a bash script that takes a file path as input, checks its current permissions and owner, and suggests the exact chmod and chown commands 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