Fix: Docker exec /entrypoint.sh: no such file or directory
Quick Answer
How to fix Docker entrypoint not found error caused by wrong file path, Windows line endings, missing shebang, wrong base image, and multi-stage build issues.
The Error
You run a Docker container and it immediately exits with:
exec /entrypoint.sh: no such file or directoryOr variations:
exec /app/start.sh: no such file or directorystandard_init_linux.go:228: exec user process caused: no such file or directoryexec /usr/local/bin/docker-entrypoint.sh: no such file or directoryOCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/entrypoint.sh": stat /entrypoint.sh: no such file or directoryDocker cannot find or execute the entrypoint script. The file either does not exist in the container, has wrong line endings, is not executable, or references a missing interpreter.
Why This Happens
When Docker starts a container, it runs the ENTRYPOINT or CMD command. If the specified file cannot be found or executed, the container fails immediately.
The confusing part: this error can appear even when the file exists in the container. The “no such file or directory” message can refer to:
- The script itself — the file path is wrong or the file was not copied.
- The interpreter — the shebang line (
#!/bin/bash) references a binary that does not exist in the image. - A linked library — the binary exists but depends on a shared library that is missing.
- Windows line endings —
\r\nline endings corrupt the shebang line, making the interpreter path invalid.
Common causes:
- Windows line endings (CRLF). The most common cause. The file was edited on Windows and has
\r\nline endings. - File not copied into the image. The
COPYorADDinstruction has the wrong path. - Wrong base image. The script uses
#!/bin/bashbut the image only has#!/bin/sh(Alpine Linux). - File not executable. The script does not have execute permissions.
- Multi-stage build. The file was in a build stage but not copied to the final stage.
- Binary compiled for wrong architecture. An amd64 binary running on an arm64 image.
Fix 1: Fix Windows Line Endings (CRLF → LF)
The most common cause. Windows text editors add \r (carriage return) characters that break the shebang line:
#!/bin/bash\r ← The \r is invisible but the kernel looks for "/bin/bash\r" which doesn't existFix in the Dockerfile:
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.shFix before building — convert on your machine:
# Using dos2unix
dos2unix entrypoint.sh
# Using sed
sed -i 's/\r$//' entrypoint.sh
# Using tr
tr -d '\r' < entrypoint.sh > entrypoint_fixed.sh && mv entrypoint_fixed.sh entrypoint.shFix with .gitattributes (permanent):
# Force LF line endings for all shell scripts
*.sh text eol=lf
entrypoint.sh text eol=lf
Dockerfile text eol=lfFix in VS Code: Click on CRLF in the bottom status bar and switch to LF.
Pro Tip: Always add a
.gitattributesfile to your project with*.sh text eol=lf. This prevents Git from converting line endings to CRLF on Windows checkouts, which is the root cause of most Docker entrypoint issues on Windows.
Fix 2: Verify the File Exists in the Image
The file might not be copied correctly:
Debug — check what is in the image:
# Run a shell in the image to inspect
docker run --rm -it --entrypoint /bin/sh myimage
# List the file
ls -la /entrypoint.sh
# Or use docker inspect
docker run --rm --entrypoint ls myimage -la /entrypoint.shCheck your COPY instruction:
# Wrong — source path is wrong
COPY ./scripts/entrypoint.sh /entrypoint.sh
# The file might be at ./entrypoint.sh, not ./scripts/
# Fixed — verify the path relative to the build context
COPY entrypoint.sh /entrypoint.shCheck .dockerignore:
# If .dockerignore contains this, the file is excluded from the build context!
*.sh
entrypoint.shRemove the entry from .dockerignore or add an exception:
*.sh
!entrypoint.shFix 3: Fix the Shebang Line
The script’s shebang must reference an interpreter that exists in the image:
Alpine Linux does not have bash by default:
#!/bin/bash ← Does NOT exist in Alpine
#!/bin/sh ← Works in Alpine (uses ash/busybox)Fix: Use sh instead of bash:
#!/bin/sh
set -e
echo "Starting application..."
exec "$@"Fix: Install bash in Alpine:
FROM alpine:3.19
RUN apk add --no-cache bash
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Fix: Use a Debian-based image that includes bash:
FROM debian:bookworm-slim
# bash is available by defaultCommon Mistake: Developing scripts on a machine with bash and deploying to Alpine containers that only have sh. If your script uses bash-specific features (arrays,
[[ ]],${var//pattern/replacement}), either install bash or rewrite using POSIX sh syntax.
Fix 4: Fix File Permissions
The entrypoint script must be executable:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Or set permissions before copying:
# On your machine
chmod +x entrypoint.sh
git add entrypoint.sh
git commit -m "Make entrypoint executable"Using COPY with —chmod (Docker BuildKit, Docker 20.10+):
# syntax=docker/dockerfile:1
COPY --chmod=755 entrypoint.sh /entrypoint.shFix 5: Fix Multi-Stage Build Issues
In multi-stage builds, files from earlier stages are not automatically available:
Broken:
FROM node:22 AS build
COPY entrypoint.sh /entrypoint.sh
RUN npm run build
FROM node:22-alpine
# entrypoint.sh is NOT here — it was in the build stage
ENTRYPOINT ["/entrypoint.sh"]Fixed — copy from the build stage:
FROM node:22 AS build
COPY entrypoint.sh /entrypoint.sh
RUN npm run build
FROM node:22-alpine
COPY --from=build /entrypoint.sh /entrypoint.sh
COPY --from=build /app/dist /app/dist
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Or copy directly in the final stage:
FROM node:22 AS build
RUN npm run build
FROM node:22-alpine
COPY entrypoint.sh /entrypoint.sh
COPY --from=build /app/dist /app/dist
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Fix 6: Fix Binary Architecture Mismatch
A binary compiled for the wrong CPU architecture triggers the same error:
# amd64 binary on arm64 platform (Apple Silicon Mac)
exec /app/myserver: no such file or directoryCheck the binary architecture:
file myserver
# myserver: ELF 64-bit LSB executable, x86-64 ← amd64Fix: Build for the correct platform:
# Build for amd64
docker build --platform linux/amd64 -t myimage .
# Build for arm64
docker build --platform linux/arm64 -t myimage .
# Build multi-platform
docker buildx build --platform linux/amd64,linux/arm64 -t myimage .For Go binaries:
GOOS=linux GOARCH=amd64 go build -o myserverFor statically linked binaries in scratch/distroless:
# Ensure static linking
CGO_ENABLED=0 GOOS=linux go build -a -o myserverFix 7: Fix ENTRYPOINT Syntax
Docker has two ENTRYPOINT forms. The wrong form can cause issues:
Exec form (recommended):
ENTRYPOINT ["/entrypoint.sh"]Shell form (runs through /bin/sh -c):
ENTRYPOINT /entrypoint.shThe exec form does NOT use a shell. If your script needs shell features, either:
- Use the shell form.
- Or explicitly call the shell:
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]CMD with ENTRYPOINT:
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--default-flag"]
# Runs: /entrypoint.sh --default-flagMake sure the entrypoint script handles $@ to pass CMD arguments:
#!/bin/sh
set -e
echo "Initializing..."
exec "$@" # Execute the CMD argumentsFix 8: Fix Missing Shared Libraries
For compiled binaries, missing shared libraries cause “no such file or directory”:
# Check what libraries the binary needs
docker run --rm --entrypoint ldd myimage /app/myserver
# libpthread.so.0 => not found
# libc.musl-x86_64.so.1 => not foundFix: Use a compatible base image:
# If compiled on Ubuntu, use Ubuntu (not Alpine)
FROM ubuntu:24.04
COPY myserver /app/myserver
# Or use Alpine if compiled with musl
FROM alpine:3.19
RUN apk add --no-cache libc6-compat # Adds glibc compatibility
COPY myserver /app/myserverFix: Compile statically:
# For Go
FROM golang:1.23 AS build
ENV CGO_ENABLED=0
RUN go build -o /myserver
FROM scratch
COPY --from=build /myserver /myserver
ENTRYPOINT ["/myserver"]Still Not Working?
Inspect the image layer by layer:
docker history myimage
docker inspect myimageUse docker run with a different entrypoint to debug:
docker run --rm -it --entrypoint /bin/sh myimage
# Then manually try running the entrypoint
/entrypoint.shCheck for invisible characters (BOM, zero-width spaces):
hexdump -C entrypoint.sh | head -5
# Should start with 23 21 2f (#!/), not EF BB BF (UTF-8 BOM)For Docker exec format errors (wrong architecture), see Fix: Docker exec format error. For Docker container name conflicts, see Fix: Docker container name already in use. For Docker permission issues, see Fix: Docker permission denied socket.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Docker container health status unhealthy
How to fix Docker container health check failing with unhealthy status, including HEALTHCHECK syntax, timing issues, missing curl/wget, endpoint problems, and Compose healthcheck configuration.
Fix: Docker build sending large build context / slow Docker build
How to fix Docker build sending large build context caused by missing .dockerignore, node_modules in context, large files, and inefficient Dockerfile layers.
Fix: Docker Compose Service failed to build / ERROR building
How to fix Docker Compose Service failed to build errors caused by wrong Dockerfile paths, YAML syntax issues, build args, platform mismatches, and network failures.
Fix: AWS CloudFormation stack in ROLLBACK_COMPLETE or CREATE_FAILED state
How to fix AWS CloudFormation ROLLBACK_COMPLETE and CREATE_FAILED errors caused by IAM permissions, resource limits, invalid parameters, and dependency failures.