problem hub
Read-only firstLinux permission denied
Trace owner, mode, ACL, symlink, and parent-directory permissions before recursive chmod or chown.
Safest first command
namei -l /var/www/example/index.html
Before you run this
Expected output: A path-by-path permission chain showing each parent directory and the final file.
When not to use it: Do not use broad recursive chmod or chown as a first response. It can expose files or break services.
Expected output example
f: /var/www/example/index.html
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-x--- root www-data www
-rw-r----- deploy www-data index.html
How to read the result
Every parent directory needs execute permission for the user or service that traverses it. The final file also needs the needed read/write/execute bit for that access path.
Trace the whole path
A readable file can still fail if a parent directory lacks execute permission. Start with the path chain.
namei -l /var/www/example/index.htmlstat -c '%A %U:%G %n' /var/www/example/index.html
Check symlinks and special bits
Symlinks, setuid bits, sticky directories, and ACLs can make a simple mode display misleading.
Common causes
- Missing execute bit on a parent directory
- Wrong owner or group after deploy
- ACL overriding simple mode bits
- Symlink target with stricter permissions
- SELinux/AppArmor denial even when Unix mode looks correct
What not to change yet
- Do not run chmod -R 777.
- Do not chown a whole web root without knowing the service user.
- Do not change symlink targets before checking the full path chain.
platform notes
Distro and service notes
Web servers
Nginx/Apache usually read as www-data, nginx, apache, or a configured service user.
macOS
BSD stat/namei behavior differs; use macOS-specific pages for Apple Terminal workflows.
SELinux/AppArmor
If modes look correct, check mandatory access-control logs before broad chmod/chown.
supporting commands