This error occurs when you try to run or exec into a Docker container using /bin/bash, but the container's image doesn't include bash. This is common with Alpine, distroless, or scratch-based images that use minimal shells like sh or ash, or have no shell at all.
The "no such file or directory" error for /bin/bash indicates that the Docker container you're trying to access doesn't have the bash shell installed. This happens because many lightweight Docker images are built to minimize size and attack surface by excluding unnecessary binaries. Alpine Linux images, which are extremely popular due to their ~5MB size, use BusyBox with ash (Almquist shell) instead of bash. Distroless images from Google and scratch-based images often have no shell at all. When you try to run `docker exec -it container /bin/bash` or set `CMD ["/bin/bash"]` in your Dockerfile, Docker can't find the executable and throws this OCI runtime error. The "OCI runtime create failed" prefix tells you this is a container creation/execution error at the runtime level, meaning the container can't even start the specified command because the binary simply doesn't exist in the image's filesystem.
The quickest fix is to use the shell that's actually available in the image. Most images include at least /bin/sh:
# Instead of this (fails on Alpine/minimal images):
docker exec -it mycontainer /bin/bash
# Use this:
docker exec -it mycontainer /bin/shFor Alpine images specifically, you can also use:
docker exec -it mycontainer /bin/ashTo check what shells are available in an image:
docker run --rm -it myimage ls -la /bin/*sh*If your Dockerfile uses bash in CMD or ENTRYPOINT, switch to sh:
# Before (fails on Alpine):
CMD ["/bin/bash", "-c", "echo hello"]
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
# After (works on all images with a shell):
CMD ["/bin/sh", "-c", "echo hello"]
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]Also update any shebang lines in your scripts:
# Before:
#!/bin/bash
# After (POSIX-compatible):
#!/bin/shNote: Using sh means you lose bash-specific features like arrays, [[ ]] conditionals, and certain string manipulations. If you need these, install bash instead.
If you need bash features, install it in your Dockerfile:
FROM alpine:latest
# Install bash
RUN apk add --no-cache bash
# Now you can use /bin/bash
CMD ["/bin/bash"]This adds about 4MB to your image size. For interactive shells:
# First, rebuild the image with bash installed
docker build -t myimage:with-bash .
# Then you can exec with bash
docker exec -it mycontainer /bin/bashYou can also install bash interactively in a running container (changes won't persist):
docker exec -it mycontainer /bin/sh -c "apk add --no-cache bash && /bin/bash"Distroless and scratch images have no shell at all. You cannot exec into them directly.
For debugging distroless images, use debug variants:
# Google's distroless images have debug tags with busybox shell
docker run -it --entrypoint /busybox/sh gcr.io/distroless/base:debugFor scratch images, you must use multi-stage builds and ensure your binary doesn't need a shell:
# Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o myapp
# Runtime stage - no shell available
FROM scratch
COPY --from=builder /app/myapp /myapp
# Must use exec form (JSON array) - shell form won't work
ENTRYPOINT ["/myapp"]To debug scratch containers, use docker cp or attach with a sidecar:
# Copy files out for inspection
docker cp mycontainer:/app/logs ./logs
# Or use docker debug (Docker Desktop 4.27+)
docker debug mycontainerWhen using minimal images, always use the exec form (JSON array) instead of shell form:
# Shell form - requires /bin/sh to parse the command (will fail on scratch)
CMD echo "hello"
ENTRYPOINT /app/start.sh
# Exec form - runs directly without a shell (works on any image)
CMD ["echo", "hello"]
ENTRYPOINT ["/app/start.sh"]The shell form implicitly wraps your command in /bin/sh -c "...". If /bin/sh doesn't exist, the container fails to start.
Mixed usage - you can use exec form ENTRYPOINT with shell form CMD for flexibility:
# Runs: /app/myapp with arguments from CMD
ENTRYPOINT ["/app/myapp"]
CMD ["--config", "/etc/app/config.yaml"]Before writing your Dockerfile or exec commands, check what's available in your base image:
# List all shell-like binaries
docker run --rm myimage ls -la /bin/ 2>/dev/null | grep -E 'sh|bash|ash|zsh'
# Check if specific shell exists
docker run --rm myimage which sh
docker run --rm myimage which bash
# Inspect the image's default shell
docker inspect --format='{{.Config.Shell}}' myimageCommon shells by base image:
- Ubuntu/Debian: bash, sh (dash)
- Alpine: ash, sh (symlink to ash)
- BusyBox: ash, sh
- Distroless: none (or busybox in :debug tags)
- Scratch: none
Windows line endings: If you're getting "not found" errors even after verifying the shell exists, check for Windows line endings (CRLF) in your scripts. Convert them:
# In Dockerfile
RUN sed -i 's/\r$//' /app/script.sh
# Or use dos2unix
RUN apk add --no-cache dos2unix && dos2unix /app/script.shGit Bash on Windows: When using Git Bash, paths get mangled. Use double slashes:
docker exec -it container //bin/shCopying a shell into scratch images: For debugging, you can copy a static shell binary:
FROM scratch
COPY --from=busybox:uclibc /bin/sh /bin/shUsing nsenter for shell-less containers: On Linux hosts, you can enter a container's namespaces directly:
# Get the container's PID
PID=$(docker inspect --format '{{.State.Pid}}' mycontainer)
# Enter all namespaces
sudo nsenter -t $PID -m -u -i -n -p /bin/shKubernetes debugging: Use ephemeral containers to debug distroless pods:
kubectl debug -it mypod --image=busybox --target=mycontainerimage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub