This error occurs when Docker cannot execute a binary or script due to architecture mismatch, missing shebang line, or incorrect file format. Common causes include running amd64 images on ARM hosts, scripts with Windows line endings (CRLF), or entrypoint files missing the #!/bin/bash shebang.
The "exec format error" in Docker indicates that the container runtime cannot execute the specified binary or script. This happens when the executable format doesn't match what the system expects. There are three main scenarios that trigger this error: 1. **Architecture mismatch**: The most common cause is trying to run a binary compiled for one CPU architecture (like x86_64/amd64) on a different architecture (like ARM64). This often happens when running images built on Intel/AMD machines on Apple Silicon Macs or Raspberry Pi devices. 2. **Script format issues**: Entrypoint scripts that lack a proper shebang line (#!/bin/bash or #!/bin/sh) will fail with this error. The kernel doesn't know which interpreter should execute the script. 3. **Line ending problems**: Scripts created on Windows have CRLF line endings instead of Unix LF endings. When Docker tries to execute these scripts, the carriage return character corrupts the shebang interpreter path, causing the exec format error. Understanding which scenario applies to your situation is crucial for applying the correct fix.
First, determine if the error is caused by running an image built for a different CPU architecture:
# Check your host architecture
uname -m
# Output: x86_64 (amd64) or aarch64 (arm64)
# Check what architecture the image was built for
docker image inspect your-image:tag --format '{{.Os}}/{{.Architecture}}'
# Or use buildx for more detailed information
docker buildx imagetools inspect your-image:tagIf the architectures don't match (e.g., image is linux/amd64 but host is aarch64), proceed to the next step for the fix.
If you need to run an image built for a different architecture, use the --platform flag:
# Run an amd64 image on an ARM host
docker run --platform linux/amd64 your-image:tag
# Run an ARM image on an amd64 host
docker run --platform linux/arm64 your-image:tagThis enables QEMU emulation (available by default in Docker Desktop). Note that emulated containers run 2-5x slower than native ones.
For a permanent solution, set the default platform:
export DOCKER_DEFAULT_PLATFORM=linux/amd64Or specify the platform in your Dockerfile's FROM line:
FROM --platform=linux/amd64 node:18-alpineIf the error mentions your entrypoint script, ensure it has a proper shebang as the very first line:
#!/bin/bash
# or for Alpine and minimal images:
#!/bin/sh
# Your script content follows...
set -e
echo "Starting application..."
exec "$@"Critical requirements:
- The shebang MUST be on line 1, character 1 (no whitespace before it)
- No blank lines before the shebang
- No Unicode BOM at the start of the file
Check your file:
# View first line with hidden characters
head -1 docker-entrypoint.sh | cat -A
# Should show: #!/bin/bash$ (the $ indicates end of line)
# Bad output: ^M#!/bin/bash$ (^M indicates Windows line ending)
# Bad output: #!/bin/bash$ (leading space)Scripts edited on Windows often have CRLF line endings that break the shebang. Convert them to Unix LF:
# Using dos2unix (install if needed: apt-get install dos2unix)
dos2unix docker-entrypoint.sh
# Or using sed
sed -i 's/\r$//' docker-entrypoint.sh
# Or in the Dockerfile to convert during build
RUN sed -i 's/\r$//' /docker-entrypoint.sh
# Verify the fix
file docker-entrypoint.sh
# Good output: "ASCII text executable"
# Bad output: "ASCII text executable, with CRLF line terminators"Prevention tip: Configure your editor or Git to use LF line endings:
# In .gitattributes
*.sh text eol=lf
Dockerfile text eol=lfThe entrypoint script must be executable. Add the permission in your Dockerfile:
# Copy and make executable in one layer
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Or combine COPY with chmod (requires BuildKit)
COPY --chmod=755 docker-entrypoint.sh /usr/local/bin/If the file is already in the container:
# Check current permissions
docker run --entrypoint /bin/sh your-image -c "ls -la /docker-entrypoint.sh"
# Fix in a new image layer
docker run your-image chmod +x /docker-entrypoint.sh
docker commit <container-id> your-image:fixedOn Linux servers (not Docker Desktop), you need to install QEMU for cross-platform emulation:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y qemu-user-static binfmt-support
# Or use Docker's QEMU setup (works on any Linux)
docker run --privileged --rm tonistiigi/binfmt --install all
# Verify QEMU is registered
ls /proc/sys/fs/binfmt_misc/qemu-*
# Test emulation
docker run --platform linux/arm64 arm64v8/alpine uname -m
# Should output: aarch64This is essential for CI/CD pipelines building multi-architecture images on x86 runners.
The best long-term solution is building images that support multiple architectures:
# Create a multi-architecture builder
docker buildx create --name multiarch-builder --use --bootstrap
# Build for multiple platforms
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag your-registry/your-image:latest \
--push \
.
# Verify the image supports multiple platforms
docker buildx imagetools inspect your-registry/your-image:latestWhen users pull this image, Docker automatically selects the correct architecture variant.
If the error appeared suddenly after a failed download or disk space issue, corrupted layers might be the cause:
# Remove the problematic image and re-pull
docker rmi your-image:tag
docker pull your-image:tag
# If that doesn't work, clean up all Docker resources
docker system prune -a
# For more aggressive cleanup (removes everything)
docker system prune -a --volumes
# Then pull fresh
docker pull your-image:tagThis ensures you have complete, uncorrupted image layers.
### Alpine Linux and Shebang Requirements
Alpine Linux is stricter about script execution than other distributions. Scripts that work on Debian/Ubuntu may fail on Alpine without a proper shebang:
# Alpine uses /bin/sh (BusyBox ash), not bash
FROM alpine:3.19
# Install bash if your script requires it
RUN apk add --no-cache bash
# Or update your script to use /bin/sh
COPY --chmod=755 entrypoint.sh /
# entrypoint.sh should start with: #!/bin/sh### Debugging the Exact Cause
To identify exactly what's failing:
# Override entrypoint to get a shell
docker run -it --entrypoint /bin/sh your-image
# Inside the container, manually test:
/docker-entrypoint.sh
# This shows the actual error
# Check the file format
file /docker-entrypoint.sh
head -1 /docker-entrypoint.sh | od -c### CI/CD Pipeline Considerations
When your pipeline runs on different architectures:
# GitHub Actions example
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
push: true
tags: user/app:latest### Windows Container vs Linux Container Mode
On Docker Desktop for Windows, ensure you're in the correct container mode:
- Linux containers: Can run linux/amd64 images with WSL2 backend
- Windows containers: Can only run Windows-based images
Right-click the Docker Desktop tray icon to switch modes. The "exec format error" can occur if you try to run Linux images in Windows container mode.
### Validating Entrypoint Scripts Before Build
Add a validation step in your CI to catch issues early:
#!/bin/bash
# validate-scripts.sh
for script in *.sh; do
# Check for shebang
if ! head -1 "$script" | grep -q '^#!'; then
echo "ERROR: $script missing shebang"
exit 1
fi
# Check for Windows line endings
if file "$script" | grep -q 'CRLF'; then
echo "ERROR: $script has Windows line endings"
exit 1
fi
echo "OK: $script"
doneimage 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