How to fix "exec format error" when running a Docker container
My Docker container exits immediately after starting with this error:
standard_init_linux.go:228: exec user process caused: exec format error
or just:
exec /usr/local/bin/entrypoint.sh: exec format error
The image builds without errors, but it crashes on any machine other than mine. What is causing this?
Solution
This error almost always means the container image was built for a different CPU architecture than the machine running it. The most common case is building on an Apple Silicon Mac (ARM64) and deploying to a Linux server (x86-64/AMD64).
Add the --platform flag to your docker build command to explicitly target the deployment architecture:
docker build --platform linux/amd64 -t my-app .
If you are using Docker Compose, set the platform in your docker-compose.yml:
services:
app:
build:
context: .
platforms:
- linux/amd64
image: my-app
Alternative #1
If you need to build images that run on both ARM64 and AMD64 (for example, to support both Apple Silicon Macs and Linux servers), use docker buildx to create a multi-platform image:
# Create and use a buildx builder that supports multiple platforms
docker buildx create --use
# Build and push a multi-platform image
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag your-registry/my-app:latest \
--push \
.
The --push flag is required for multi-platform builds because Docker cannot load a multi-platform image into the local daemon. The image manifest will include both architectures and Docker will pull the correct one automatically.
Alternative #2
If your entrypoint is a shell script, the error can also be caused by missing the shebang line or by Windows-style line endings (\r\n). Check that your script starts with #!/bin/sh or #!/bin/bash and that it uses Unix line endings:
#!/bin/sh
# This line is required - without it, the kernel does not know how to execute the file
set -e
exec "$@"
To convert a script from Windows to Unix line endings on macOS or Linux:
sed -i 's/\r//' entrypoint.sh
Or using dos2unix:
dos2unix entrypoint.sh
Alternative #3
In GitHub Actions, you can set the platform directly in the build step when using docker/build-push-action:
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: your-registry/my-app:latest
This ensures images built in CI are always compatible with your deployment targets, regardless of the runner architecture.