KhueApps
Home/DevOps/Fix Docker 'no such file or directory' (CRLF, shebang)

Fix Docker 'no such file or directory' (CRLF, shebang)

Last updated: October 06, 2025

Overview

In Docker, the message "exec user process caused: no such file or directory" usually appears when the container tries to exec your entrypoint or CMD and the kernel cannot run it. The most common causes are:

  • CRLF line endings in scripts copied from Windows
  • Missing or wrong shebang (e.g., script lacks #!/bin/sh or points to a non-existent interpreter)
  • Not executable (missing +x)
  • Wrong path in ENTRYPOINT/CMD

This guide focuses on CRLF and shebang issues and shows quick, reliable fixes for DevOps/Docker workflows.

Quickstart (TL;DR)

  • Ensure scripts use LF line endings.
  • Add a valid shebang that exists in the image, e.g., #!/bin/sh or #!/usr/bin/env bash (if bash is installed).
  • Make scripts executable at build time.
  • Use JSON exec form for ENTRYPOINT/CMD.

Commands and Dockerfile hints:

# Convert line endings in your repo (host):
dos2unix entrypoint.sh  # or: sed -i 's/\r$//' entrypoint.sh

# Enforce LF in Git (add to .gitattributes):
echo "*.sh text eol=lf" >> .gitattributes

git add .gitattributes entrypoint.sh && git commit -m "Enforce LF for scripts"
# Dockerfile (with BuildKit)
FROM alpine:3.20
COPY --chmod=0755 entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

Ensure the script starts with:

#!/bin/sh
set -eu

Minimal working example

Broken example (reproduces the error)

Files:

# Dockerfile
FROM alpine:3.20
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# entrypoint.sh (saved with CRLF and NO shebang)
echo "It ran"

Build and run:

docker build -t crlf-demo .
docker run --rm crlf-demo
# => exec user process caused: no such file or directory

Why it fails:

  • The script has CRLF endings. The kernel reads \r before \n, can’t parse the interpreter line (there isn’t one), and fails to exec.

Fixed example

Make the following changes:

  1. Add a valid shebang and ensure LF endings:
#!/bin/sh
set -eu
echo "It ran"
  1. Enforce execute permissions at build time and use JSON exec form:
# Dockerfile (fixed)
FROM alpine:3.20
COPY --chmod=0755 entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

Build and run:

docker build -t crlf-demo-fixed .
docker run --rm crlf-demo-fixed
# => It ran

Step-by-step diagnosis

  1. Confirm the entrypoint path
    • Check your Dockerfile:
      • ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
      • Ensure the path exists inside the image.
    • Quick check:
docker run --rm -it --entrypoint /bin/sh crlf-demo -c \
  'ls -l /usr/local/bin/entrypoint.sh || echo missing'
  1. Check if the file is executable
docker run --rm -it --entrypoint /bin/sh crlf-demo -c \
  'ls -l /usr/local/bin/entrypoint.sh'
# Expect: -rwxr-xr-x

If not, fix your Dockerfile to set the mode during COPY or run chmod +x in a build step.

  1. Detect CRLF line endings
  • On host:
hexdump -C entrypoint.sh | head  # Look for 0d 0a (\r\n) at line ends
# or
file entrypoint.sh  # Often reports "CRLF line terminators"
  • Inside the image:
docker run --rm -it --entrypoint /bin/sh crlf-demo -c \
  'od -An -t x1 -c /usr/local/bin/entrypoint.sh | head'
# 0d 0a indicates CRLF

If CRLF found, convert to LF and prevent reintroduction (see Git settings below).

  1. Verify the shebang and interpreter
  • First line must be a valid interpreter path present in the image:
    • Alpine: use #!/bin/sh (BusyBox ash) unless you install bash.
    • If you prefer bash: #!/usr/bin/env bash and apk add --no-cache bash.
  1. Use JSON exec form to avoid shell quirks
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# And if you pass args:
CMD ["--verbose"]

Make CRLF problems go away (Git settings)

  • In your repo, add .gitattributes:
*.sh text eol=lf
Dockerfile text eol=lf
  • Optionally set per-repo policy:
git config core.autocrlf false
  • Normalize existing files (one-time):
git rm --cached -r .
git reset --hard
  • If needed, convert current files:
dos2unix entrypoint.sh  # or: sed -i 's/\r$//' entrypoint.sh

Common pitfalls and fixes

  • Missing shebang with exec-form ENTRYPOINT

    • Symptom: "exec format error" or the same "no such file or directory".
    • Fix: Add #!/bin/sh (or the interpreter you actually have installed).
  • Wrong interpreter path

    • Example: #!/bin/bash on Alpine (bash not installed by default).
    • Fix: Use #!/bin/sh or install bash.
  • Missing execute bit

    • Fix at build time: COPY --chmod=0755 script.sh /usr/local/bin/ (requires BuildKit) or RUN chmod +x /usr/local/bin/script.sh.
  • Hidden CRLF after templating

    • Some CI/templating steps reintroduce CRLF. Validate in CI with a check step that fails builds if CRLF is found.

Performance notes

  • Set permissions during COPY: COPY --chmod=0755 avoids extra RUN chmod layers and speeds up builds.
  • Prevent CRLF at the source (Git attributes) rather than fixing in the image (avoids installing tools like dos2unix in build stages).
  • Use multi-stage builds to keep runtime images minimal if you need conversion utilities during build.
  • Prefer JSON exec form for ENTRYPOINT/CMD to avoid spawning extra shells and reduce startup overhead.

Tiny FAQ

  • Q: Why does it work on my host but fail in Docker?

    • A: Your host shell may execute the script via a shell that tolerates CRLF or handles missing shebangs. Docker uses exec form without a shell unless you explicitly invoke one.
  • Q: How do I verify line endings quickly?

    • A: file script.sh (host) or hexdump -C script.sh | head and look for 0d 0a. No 0d means LF only.
  • Q: Do I need bash?

    • A: Not usually. Use #!/bin/sh for portability. If you require bash features, install it and use #!/usr/bin/env bash.
  • Q: I fixed CRLF but still get errors.

    • A: Recheck: correct path in ENTRYPOINT, executable bit set, interpreter exists, and JSON exec form used.
  • Q: Can I fix permissions without BuildKit?

    • A: Yes, use a RUN chmod +x /path/script.sh layer after copying the file.

Series: Docker

DevOps