Docker Error Guide: 'OCI runtime exec failed: permission denied' — Fix Non-Executable Entrypoints
Fix Docker 'OCI runtime exec failed permission denied': set the executable bit on entrypoints, handle CRLF and missing interpreters, and resolve noexec mounts and security policies.
- #docker
- #troubleshooting
- #errors
- #permissions
Stuck on this Docker with AI 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
Docker (via runc) raises this when it can locate the process you asked to run but the kernel refuses to execute it:
OCI runtime exec failed: exec failed: unable to start container process: exec: "/entrypoint.sh": permission denied: unknown
The same shape appears on docker run (unable to start container process) and on docker exec. The key phrase is permission denied — the file exists, but it is either not executable, has a broken interpreter line, or is being run from a mount that forbids execution.
Symptoms
docker runexits immediately withOCI runtime create failed ... permission denied.docker exec -it <id> /some/script.shreturnspermission deniedeven though the file is clearly present.- The image built fine but never starts; the entrypoint script is the culprit.
- A bind-mounted script works on one host and fails on another.
Common Root Causes
- Missing executable bit — the entrypoint or command file was copied without
+x(common when scripts are added on a Windows or CI filesystem). - CRLF line endings / bad shebang — a script starting with
#!/bin/sh\rmakes the kernel look for an interpreter namedsh\r, which fails. - Missing interpreter — the shebang points to
/bin/bashbut the (slim/alpine) image only has/bin/sh. - noexec mount — the script lives on a bind mount or tmpfs mounted with
noexec, so execution is blocked regardless of file bits. - Directory, not a file — the entrypoint path resolves to a directory.
- Security policy — SELinux, AppArmor, or a seccomp profile denies the exec.
Diagnostic Workflow
Verify the file’s permissions and type inside the image without running the failing entrypoint:
docker run --rm --entrypoint sh myapp:1.4.2 -c 'ls -l /entrypoint.sh; file /entrypoint.sh'
A mode like -rw-r--r-- (no x) is the smoking gun. Check the shebang and hunt for a carriage return:
docker run --rm --entrypoint sh myapp:1.4.2 -c 'head -1 /entrypoint.sh | od -c | head -1'
A trailing \r confirms CRLF endings. Confirm the interpreter actually exists:
docker run --rm --entrypoint sh myapp:1.4.2 -c 'ls -l /bin/bash /bin/sh 2>&1'
If the script is bind-mounted, check for a noexec mount on the host:
mount | grep noexec
For security-policy denials, check the daemon and kernel logs:
journalctl -u docker --since '10 min ago' | grep -i 'permission\|apparmor\|seccomp'
dmesg | tail -20 | grep -i 'denied\|apparmor'
Example Root Cause Analysis
A CI pipeline built myapp:1.4.2 successfully, but every deploy crashed with OCI runtime create failed: unable to start container process: exec: "/entrypoint.sh": permission denied.
Inspecting the file inside the image showed no executable bit:
docker run --rm --entrypoint sh myapp:1.4.2 -c 'ls -l /entrypoint.sh'
# -rw-r--r-- 1 root root 412 /entrypoint.sh
The Dockerfile had COPY entrypoint.sh /entrypoint.sh but never made it executable, and the source file (checked out on a Windows CI runner) had lost its mode bit. The fix was to set the bit explicitly at build time and normalize line endings:
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
After rebuilding, ls -l showed -rwxr-xr-x and the container started cleanly.
Prevention Best Practices
- Always
chmod +xentrypoint scripts in the Dockerfile (or commit them with the executable bit and a.gitattributes* text=auto eol=lfrule to prevent CRLF). - Match the shebang to what the base image ships — use
#!/bin/shfor alpine/slim images that lack bash. - Avoid mounting scripts from
noexecfilesystems; bake them into the image instead. - Prefer the exec form (
ENTRYPOINT ["/entrypoint.sh"]) and test the image locally before shipping. - Lint your build with the Dockerfile validator and follow the runtime conventions in the Docker stack guide.
Quick Command Reference
docker run --rm --entrypoint sh myapp:1.4.2 -c 'ls -l /entrypoint.sh; file /entrypoint.sh'
docker run --rm --entrypoint sh myapp:1.4.2 -c 'head -1 /entrypoint.sh | od -c | head -1' # CRLF check
mount | grep noexec # noexec bind mount?
dmesg | tail -20 | grep -i 'apparmor\|denied' # security policy?
# In the Dockerfile:
# RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
Conclusion
OCI runtime exec failed ... permission denied means the kernel found the file but would not run it. Ninety percent of the time it is a missing executable bit or CRLF line endings on the entrypoint; the rest is a missing interpreter, a noexec mount, or a security policy. Inspect the file with ls -l and check the shebang, then fix the root cause in the Dockerfile with chmod +x and LF normalization rather than working around it at runtime.
Fixed it? Get 500 Docker with AI & 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.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
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.