How to Fix Docker 'standard_init_linux.go:211: exec user process caused: no such file or directory'
Threat/Impact Level: CRITICAL | Exploitability/Downtime Risk: HIGH | Time to Fix: 5 mins
TL;DR
- What broke: Docker's Linux init layer cannot execute your entrypoint — the file either has Windows CRLF line endings, a wrong shebang, missing execute bit, or simply doesn't exist at the declared path inside the image.
- How to fix it: Strip CRLF endings with
dos2unix, verify the shebang,chmod +xthe script, and confirm the binary path is valid inside the container filesystem. - Fast path: Use our Client-Side Sandbox below to auto-refactor your Dockerfile and entrypoint script — paste both and get corrected code instantly.
The Incident (What Does the Error Mean?)
Raw error output from docker run or your Kubernetes pod events:
standard_init_linux.go:211: exec user process caused: no such file or directory
This fires inside runc's init process — the very first thing that runs inside the container namespace. The kernel's execve() syscall returned ENOENT. Your application process never started. The container exits with code 1 immediately. In Kubernetes this manifests as CrashLoopBackOff within seconds of scheduling.
Despite the message saying "no such file or directory", the script file itself usually exists. The error is thrown by the kernel when it cannot find the interpreter declared in the shebang line (e.g., #!/bin/bash when bash isn't installed, or a path with invisible \r characters corrupting the interpreter path).
The Attack Vector / Blast Radius
This is a full deployment blocker. Every replica of your service fails simultaneously on rollout. In a CD pipeline with auto-deploy, a single bad commit carrying a CRLF-encoded entrypoint script takes down all pods in the Deployment. kubectl rollout undo is your immediate escape hatch, but the root cause will re-emerge on every subsequent deploy until fixed at the source.
Cascading failure chain:
- New image pushed → rolling update starts
- All new pods hit
CrashLoopBackOff - If
maxUnavailableis misconfigured, old pods are terminated before new ones are healthy - Service goes dark
The CRLF variant is especially insidious because cat entrypoint.sh looks perfectly normal in a Windows terminal. The corruption is invisible without cat -A or hexdump.
How to Fix It (The Solution)
Diagnose First
Run these inside your build context before building:
# Detect CRLF — if you see ^M at line endings, that's your culprit
cat -A entrypoint.sh | head -5
# Verify shebang interpreter exists in the base image
docker run --rm <base-image> which bash
docker run --rm <base-image> ls -la /bin/sh
# Inspect the built image filesystem directly
docker run --rm --entrypoint sh <your-image> -c "ls -la /app/entrypoint.sh"
Root Cause 1 — CRLF Line Endings (Most Common)
- #!/bin/bash\r\n ← Windows line ending, kernel sees interpreter as "/bin/bash\r"
- set -e\r\n
- exec "$@"\r\n
+ #!/bin/bash
+ set -e
+ exec "$@"
Fix in Dockerfile:
COPY entrypoint.sh /entrypoint.sh
+ RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Or fix at the source permanently with dos2unix entrypoint.sh and commit the clean file.
Root Cause 2 — Missing Execute Permission
COPY entrypoint.sh /entrypoint.sh
- ENTRYPOINT ["/entrypoint.sh"]
+ RUN chmod +x /entrypoint.sh
+ ENTRYPOINT ["/entrypoint.sh"]
Root Cause 3 — Wrong Shebang / Missing Interpreter
- #!/bin/bash ← bash not present in alpine-based images
+ #!/bin/sh ← sh is always available
Or install bash explicitly:
FROM alpine:3.19
+ RUN apk add --no-cache bash
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Root Cause 4 — Shell Form vs Exec Form Entrypoint
If your ENTRYPOINT uses shell form, Docker wraps it in /bin/sh -c, which can mask path issues. Always use exec form for entrypoints:
- ENTRYPOINT /entrypoint.sh
+ ENTRYPOINT ["/entrypoint.sh"]
Enterprise Best Practice
For production images, enforce entrypoint hygiene in a multi-stage build and validate during CI:
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM node:20-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY entrypoint.sh /entrypoint.sh
+ RUN dos2unix /entrypoint.sh 2>/dev/null || sed -i 's/\r$//' /entrypoint.sh \
+ && chmod 550 /entrypoint.sh \
+ && sh -n /entrypoint.sh
USER node
ENTRYPOINT ["/entrypoint.sh"]
The sh -n /entrypoint.sh performs a syntax-only check at build time — if the script is unparseable, the image build fails, not the runtime.
💡 Tired of pasting proprietary configs into ChatGPT? Generic AI tools log your company's ARNs, DB strings, and private keys. StackEngine is a zero-backend, pure Client-Side WASM utility. Drop your failing config into the sandbox above. We redact your secrets locally in the browser and auto-generate the refactored code using your own API key.
Prevention in CI/CD
1. Git — Enforce LF at the Repository Level
Add a .gitattributes file to your repo root:
# Force LF for all shell scripts committed to the repo
*.sh text eol=lf
Dockerfile text eol=lf
This prevents CRLF from ever being committed from a Windows workstation.
2. Hadolint — Dockerfile Linter in CI
# .github/workflows/lint.yml
- name: Lint Dockerfile
uses: hadolint/[email protected]
with:
dockerfile: Dockerfile
Hadolint rule DL4006 flags missing set -o pipefail and improper ENTRYPOINT forms.
3. Docker Build-Time Validation
Add a CI step that runs the container with --entrypoint overridden to validate the script exists and is executable before promoting the image:
docker build -t myapp:${GIT_SHA} .
docker run --rm --entrypoint sh myapp:${GIT_SHA} -c "
test -x /entrypoint.sh || (echo 'entrypoint not executable' && exit 1)
file /entrypoint.sh | grep -v CRLF || (echo 'CRLF detected' && exit 1)
"
4. OPA / Conftest Policy
# policy/docker.rego
package docker
deny[msg] {
input.Entrypoint[_] == cmd
not startswith(cmd, "/")
msg := sprintf("ENTRYPOINT '%v' must use an absolute path", [cmd])
}
Run with conftest test Dockerfile in your pipeline to block non-absolute entrypoint declarations before they ever reach a registry.