Docker Error Guide: 'exec /entrypoint.sh: no such file or directory' Entrypoint Startup Failures
Fix Docker 'exec /entrypoint.sh: no such file or directory': repair CRLF line endings, missing shells, wrong arch, and unset executable bits on entrypoints.
- #docker
- #troubleshooting
- #errors
- #runtime
Exact Error Message
exec ...: no such file or directory fires the instant a container starts and the runtime tries to execute its entrypoint or command:
docker run app:latest
exec /entrypoint.sh: no such file or directory
It also appears for binaries and interpreters, often confusingly when the file clearly exists:
exec /usr/local/bin/app: no such file or directory
exec /app/server: exec format error
The container exits immediately with a non-zero code. The image built fine; the failure is purely at process exec.
What the Error Means
When a container starts, the OCI runtime calls execve() on the configured entrypoint/command. The kernel’s execve returns ENOENT (“no such file or directory”) in three situations that all surface as the same message:
- The file itself is missing at the path Docker tried — a real “not found.”
- The interpreter named in the shebang is missing. For a script starting with
#!/bin/bash, if/bin/bashdoesn’t exist in the image (common onalpine, which has/bin/shbut not bash), the kernel reportsENOENTfor the interpreter, not the script — but the error names the script. - The shebang line is corrupted by CRLF line endings. A script edited on Windows ends its shebang with
\r, so the kernel looks for/bin/bash\r, which doesn’t exist — againENOENT.
A close cousin, exec format error, means the file exists and is reachable but is built for the wrong architecture (an amd64 binary on arm64) or isn’t a valid executable. The no such file or directory family is overwhelmingly shebang/CRLF/missing-interpreter, not a truly absent file.
Common Causes
- CRLF line endings in the script, so the shebang becomes
#!/bin/sh\r. - Missing interpreter —
#!/bin/bashin an image that only ships/bin/sh(alpine/distroless/scratch). - The entrypoint genuinely isn’t in the image (wrong
COPYpath, copied to the wrong stage, or.dockerignoreexcluded it). - Not executable — the file lacks the
+xbit (surfaces as permission denied or, combined with shebang issues, as not found). - Wrong architecture — an image or binary built for a different CPU (
exec format error). - Dynamically linked binary in
scratch/distroless missing its loader (/lib/ld-muslor glibc), which the kernel reports as not found.
How to Reproduce the Error
Author a script with Windows line endings and run it in a container:
printf '#!/bin/sh\r\necho hello\r\n' > entrypoint.sh
chmod +x entrypoint.sh
printf 'FROM alpine:3.20\nCOPY entrypoint.sh /entrypoint.sh\nENTRYPOINT ["/entrypoint.sh"]\n' > Dockerfile
docker build -t crlf-demo . && docker run --rm crlf-demo
exec /entrypoint.sh: no such file or directory
Diagnostic Commands
First confirm whether the file is even in the image and is executable. Override the entrypoint to get a shell:
docker run --rm -it --entrypoint sh app:latest -c 'ls -l /entrypoint.sh; head -1 /entrypoint.sh | cat -A'
cat -A reveals a trailing ^M$ (CRLF) on the shebang line — the smoking gun. Check the interpreter exists:
docker run --rm -it --entrypoint sh app:latest -c 'ls -l /bin/bash /bin/sh 2>&1'
Confirm the image/binary architecture matches the host:
docker image inspect app:latest --format 'image: {{.Architecture}}'
docker version --format 'engine: {{.Server.Arch}}'
Read the daemon log for the runtime’s exec failure:
journalctl -u docker --since "10 min ago" | grep -i 'exec\|no such file\|format error'
Step-by-Step Resolution
Cause: CRLF line endings. Convert the script to Unix endings and rebuild. In the Dockerfile you can also normalize during build, or fix the source with dos2unix/sed before COPY. The reliable fix is at the source so it can’t regress:
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
Cause: missing interpreter. Either change the shebang to one the image has (#!/bin/sh on alpine) or install the interpreter (RUN apk add bash). For distroless/scratch, ship a static binary or include the shell explicitly.
Cause: file not in image. Verify the COPY source path, the build stage, and .dockerignore. The ls -l from the diagnostics confirms presence; fix the COPY so the file lands at the expected path.
Cause: not executable. Add the bit in the Dockerfile so it’s baked into the layer:
RUN chmod +x /entrypoint.sh
Cause: wrong architecture (exec format error). Pull/build for the host’s platform, or run under emulation. Build with --platform matching the target and verify with docker image inspect.
A worked example. A developer’s image ran fine on their Mac but every teammate on Linux hit exec /entrypoint.sh: no such file or directory. The script had been committed with CRLF endings from a Windows editor; the Mac’s tooling tolerated it but the Linux kernel looked for /bin/sh\r. docker run --entrypoint sh ... -c 'head -1 /entrypoint.sh | cat -A' showed #!/bin/sh^M$. Adding RUN sed -i 's/\r$//' /entrypoint.sh to the Dockerfile and a .gitattributes rule (*.sh text eol=lf) fixed it permanently across the team.
Prevention and Best Practices
- Enforce LF endings on shell scripts with a
.gitattributesrule (*.sh text eol=lf) and a lint check in CI. - Match the shebang to what the base image actually ships (
/bin/shon alpine; install bash if you need it). - Set the executable bit in the Dockerfile (
RUN chmod +x ...) rather than relying on the host file mode. - Build for the correct
--platformand verify image architecture before deploying. - For scratch/distroless, prefer static binaries or include the interpreter and its loader explicitly.
Related Errors
- Docker Error Guide: ‘executable file not found in $PATH’ — when the command name can’t be resolved on PATH at all.
- Docker Error Guide: ‘no matching manifest for linux/amd64’ — the architecture-mismatch cousin at pull time.
- See more Docker troubleshooting guides.
Frequently Asked Questions
The file is clearly there — why “no such file”? The kernel is usually reporting the interpreter in the shebang (or a \r-mangled version of it) as missing, not the script. Inspect the first line with cat -A.
How do I tell CRLF from a missing interpreter? head -1 file | cat -A shows ^M$ for CRLF. If the shebang is clean, check that the named interpreter (/bin/bash) exists in the image.
What’s the difference from exec format error? That means the file is found and runnable but built for the wrong architecture or isn’t a valid binary. no such file is about the path/interpreter, not the binary format.
Does chmod +x on my host fix it? Only if you re-COPY after, and only for the exec bit. CRLF and missing-interpreter problems need a content/shebang fix, not just permissions.
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.