Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 10 min read

Linux Error: No such file or directory (when the file clearly exists) — Cause, Fix, and Troubleshooting Guide

How to fix Linux 'No such file or directory' when the file exists: missing ELF interpreter/loader, wrong architecture, and missing shared libraries explained.

  • #linux
  • #troubleshooting
  • #shell

Summary

No such file or directory when the file is right there in ls output is one of Linux’s most confusing errors. The file the kernel cannot find is usually not the one you named — it is a dependency the binary silently requires: its ELF interpreter (the dynamic loader, e.g. /lib64/ld-linux-x86-64.so.2), a shared library, or an interpreter for the wrong architecture. The ENOENT error refers to that missing loader or .so, not the executable you can plainly see.

Common Symptoms

  • bash: ./app: No such file or directory while ls -l ./app shows the file present and executable.
  • A statically-labeled or musl binary fails on a glibc host (or the reverse).
  • An Alpine-built binary fails to run on Ubuntu (missing ld-musl).
  • A cross-arch binary (arm64 on amd64) that reports No such file or directory instead of Exec format error.
  • docker run of a scratch/distroless image exits immediately with this error.

Most Likely Causes of the ‘No such file or directory’ Error

Production causes, most common first:

  1. Missing ELF interpreter (dynamic loader). The binary was linked against a loader path that does not exist on this host — e.g. an Alpine/musl binary (/lib/ld-musl-x86_64.so.1) on a glibc distro, or a glibc binary on Alpine. The kernel cannot find the loader, so it reports ENOENT.
  2. Wrong CPU architecture. An arm64 binary on amd64 may point at an interpreter path that is absent, surfacing as this error rather than Exec format error.
  3. Missing shared library at load time. A required .so cannot be resolved, and ld.so reports it as not found.
  4. Broken shebang / interpreter path on a script (the #! names a missing binary) — a cousin of the “bad interpreter” error.
  5. Symlink pointing at a nonexistent target. ls shows the link; the target is gone.
  6. 32-bit binary with no 32-bit loader installed on a 64-bit-only host.

Quick Triage

# The file exists — but what does it need?
file ./app

# Which loader does it want, and is it present?
readelf -l ./app | grep interpreter

# Are its libraries resolvable?
ldd ./app

If file says dynamically linked, interpreter /lib/ld-musl-x86_64.so.1 and that path is missing, you found it.

Diagnostic Commands

file ./app

For a dynamically linked ELF it prints the requested interpreter path. If that path does not exist on the host, this is your root cause.

readelf -l ./app | grep -i 'interpreter\|INTERP'

Shows the exact PT_INTERP loader the binary requires, e.g. /lib64/ld-linux-x86-64.so.2 (glibc) or /lib/ld-musl-x86_64.so.1 (musl). Then check it exists: ls -l <that path>.

ldd ./app

Lists shared-library dependencies and flags any as not found. Note: ldd on a wrong-arch binary may itself error — cross-check with readelf.

readelf -d ./app | grep NEEDED

The NEEDED entries are the exact .so names required — safer than ldd (which executes the loader) for untrusted binaries.

uname -m

Host architecture. Compare against readelf -h ./app to rule out an arch mismatch.

ls -l ./app
namei -l ./app

namei -l walks every path component (and follows symlinks), exposing a dangling symlink or an unreadable directory in the path.

Fix / Remediation

  1. Match the libc / distro. If it is a musl (Alpine) binary, run it on Alpine or install the musl loader; if it is a glibc binary, run it on a glibc base. The cleanest fix is to run the binary on the base image it was built for.

  2. Install the missing loader / 32-bit support.

    # 32-bit glibc loader on 64-bit host
    dpkg --add-architecture i386 && apt update && apt install libc6:i386   # Ubuntu/Debian
    dnf install glibc.i686                                                 # RHEL/Rocky
  3. Resolve missing shared libraries. Find and install the package that provides the .so, then refresh the cache:

    ldd ./app | grep 'not found'
    apt-file search libssl.so.3     # Ubuntu/Debian (apt-file)
    dnf provides '*/libssl.so.3'    # RHEL/Rocky
    sudo ldconfig
  4. Rebuild for the correct architecture when readelf -h and uname -m disagree (see the Exec format error guide).

  5. Fix a dangling symlink. Repoint or recreate the target:

    namei -l ./app          # find the broken component
    ln -sf /real/target ./app
  6. As a last resort, statically link the binary (CGO_ENABLED=0 for Go, -static for C) so it carries no external loader dependency.

    Warning: Do not ldconfig or drop .so files into /lib manually to silence the error — mismatched libraries can destabilize every dynamically linked program on the host. Install via the package manager.

Validation

file ./app                          # interpreter path now exists
ls -l "$(readelf -l ./app | grep -oP '/[^]]+ld[^]]+')"   # loader present
ldd ./app                           # no 'not found' lines
./app --version                     # runs

Prevention

  • Build and run binaries on matching base images (musl↔Alpine, glibc↔Debian/RHEL); pin the same base in build and runtime stages.
  • Prefer static linking for portable CLIs (CGO_ENABLED=0 go build).
  • In multi-stage Docker builds, copy binaries into a runtime image that actually has the required loader and libraries.
  • Verify with ldd in CI before shipping an image.
  • Standardize architecture across the fleet, or build multi-arch images.

Final Notes

When ls shows the file but the kernel says No such file or directory, it is almost never lying about your executable — it is telling you the loader or a library the executable depends on is missing. file, readelf -l, and ldd name the missing piece in one line. Match the libc and architecture the binary was built for, and the error disappears.

Want faster Linux incident response? Use DevOps AI Toolkit to turn production errors into clear diagnostics, remediation steps, and reusable runbooks.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

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.