Linux Error Guide: 'cannot access: No such file or directory' — Fix stat Access Errors
Fix Linux 'cannot access' and 'cannot statx: Permission denied' errors from ls and stat: diagnose a missing directory execute bit, wrong path, broken symlink, or bad mount.
- #linux
- #troubleshooting
- #errors
- #filesystem
Stuck on this Linux Admins error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
“Cannot access” errors come from stat()/statx() — the call ls, stat, and countless tools use to look up a file’s metadata. Two variants dominate, and they point at different causes:
$ ls -l /srv/app/config.yml
ls: cannot access '/srv/app/config.yml': No such file or directory
$ stat /srv/app/config.yml
stat: cannot statx '/srv/app/config.yml': Permission denied
No such file or directory (ENOENT) means the path — as resolved — points at nothing. Permission denied (EACCES) means the path exists but you lack the rights to traverse or reach it. Because stat must walk every directory in the path, a permission or existence problem anywhere along that path produces the error, even if the final file is fine.
Symptoms
ls -l <file>printscannot access '<file>': No such file or directorywhile you’re sure the file exists.stat/lsreportscannot statx '<file>': Permission denied.- A wildcard expands to nothing and the literal glob is reported as missing.
- Tab-completion fails to complete a path you expect to exist.
- A file “disappears” after a mount point unmounts, exposing the empty directory beneath.
Common Root Causes
- Wrong or mistyped path — a typo, wrong case (Linux is case-sensitive), or relative-vs-absolute confusion.
- Missing directory execute bit — a parent directory lacks
x, so you can’t traverse into it tostatthe file; this yieldsPermission denied. - Broken symlink — the link exists but its target is gone, so following it reports
No such file or directory. - Unmounted filesystem — the file lives on a mount that isn’t mounted; the underlying empty directory shows the file as missing.
- Trailing whitespace / hidden characters — a stray space or
\rin the filename means the name you type doesn’t match. - Deleted or moved file — the file was removed, rotated, or relocated since you last saw it.
Diagnostic Workflow
Test the two variants apart. For No such file or directory, confirm what actually exists at each path level:
ls -ld /srv /srv/app # walk down; find where the path breaks
namei -l /srv/app/config.yml # resolves each component, shows missing/denied step
For Permission denied, namei -l reveals the directory missing an execute bit:
namei -m /srv/app/config.yml # -m prints mode of each path component
Rule out a broken symlink (link present, target gone):
ls -l /srv/app/config.yml # 'l' type with -> target
readlink -f /srv/app/config.yml # resolves target; empty/error if broken
test -e /srv/app/config.yml && echo exists || echo "missing or broken link"
Confirm the expected filesystem is actually mounted:
mountpoint -q /srv/app && echo mounted || echo "NOT mounted"
findmnt /srv/app
Catch hidden characters in the name:
ls -b /srv/app/ # print non-printing chars as escapes (\ , \t)
Example Root Cause Analysis
A deploy script failed with the config “missing,” yet the file clearly existed for root:
$ ls -l /srv/app/config.yml # as root
-rw-r--r-- 1 root root 812 Jul 7 config.yml
$ sudo -u appsvc ls -l /srv/app/config.yml
ls: cannot access '/srv/app/config.yml': Permission denied
Root saw it, the service user got Permission denied — a traversal problem. namei -m pinpointed the offending directory:
$ namei -m /srv/app/config.yml
drwxr-xr-x /
drwxr-xr-x srv
drw-r----- app # <- no execute bit for group/other
-rw-r--r-- config.yml
/srv/app was mode 640 (drw-r-----) — readable but not traversable. Without the x bit, appsvc could not enter the directory to stat the file, so ls reported it as inaccessible. Adding execute (traverse) for the owning group fixed it:
sudo chmod 750 /srv/app # rwx for owner, r-x for group
If instead namei had shown a missing component, the fix would have been correcting the path or mounting the filesystem; a broken symlink would have called for repointing the link.
Prevention Best Practices
- Give directories the execute bit that files inside them need for traversal (
750/755), separate from the read bit. - Prefer absolute paths in scripts and services so the working directory can’t change what a relative path resolves to.
- Validate paths at startup (
test -e,test -r) and fail with a clear message rather than a rawstaterror. - Use
readlink -fin automation to detect broken symlinks before acting on them. - Add
x-systemd.requires/properfstabordering (or checkmountpoint) so services don’t run before their mounts are ready. - Avoid spaces and special characters in filenames used by automation to prevent name-matching surprises.
Quick Command Reference
namei -l <path> # resolve each path component (exists? denied?)
namei -m <path> # show mode of every component
ls -ld <dir> # directory perms (need x to traverse)
readlink -f <link> # resolve symlink target
test -e <path> && echo ok || echo missing
mountpoint -q <dir> && echo mounted # is the filesystem mounted?
ls -b <dir> # reveal hidden chars in names
Conclusion
cannot access ... No such file or directory and cannot statx ... Permission denied are stat() failures walking a path. The distinction is the whole fix: ENOENT means something in the path doesn’t exist (typo, broken symlink, unmounted filesystem), while EACCES almost always means a parent directory is missing its execute/traverse bit. Reach for namei -l/namei -m first — it shows you exactly which component of the path is missing or denied, so you stop guessing about the final file.
Fixed it? Get 500 Linux Admins & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.