Docker: standard_init_linux.go — exec format error

Quick answer

Almost always an architecture mismatch — an amd64 image running on an arm64 host (Apple Silicon) or vice versa. Run/build for the right arch: --platform linux/amd64 to emulate, or a native/multi-arch image via docker buildx. The other cause is a script entrypoint missing a shebang (#!/bin/sh) or saved with CRLF line endings.

The exact error string

standard_init_linux.go:228: exec user process caused: exec format error

# newer Docker / runc wording:
# exec /app: exec format error
# exec /usr/local/bin/entrypoint.sh: exec format error

The kernel was handed a binary it can't run. The format doesn't match the CPU — usually because the image was built for a different architecture than the machine it's running on.

Step 1: confirm the architecture

Compare the image's architecture with the host's. A mismatch is the cause in the large majority of cases:

docker image inspect myimage --format '{{.Architecture}}'   # e.g. amd64
uname -m                                                    # host: arm64 / aarch64 or x86_64

Fix 1: run for the right architecture

On Apple Silicon (arm64), an amd64-only image needs emulation, or — better — a native arm64 image:

# run an amd64 image under emulation on arm64 (works, slower)
docker run --platform linux/amd64 myimage

# prefer a native image when one exists
docker pull --platform linux/arm64 myimage

Fix 2: build for the target architecture

If you build on one arch and deploy on another (e.g. build on an M-series Mac, deploy to an amd64 server), build for the target — or publish a multi-arch image with buildx:

# build specifically for the deploy target
docker build --platform linux/amd64 -t myimage .

# one image that runs on both architectures
docker buildx build --platform linux/amd64,linux/arm64 -t myrepo/myimage --push .

Fix 3: a script entrypoint with no shebang

If the architectures match, suspect the entrypoint script. Without a shebang on the first line, the kernel can't choose an interpreter and reports exec format error:

#!/bin/sh
# ^ must be the very first line of entrypoint.sh

echo "starting..."
exec "$@"

Also make it executable in the image: RUN chmod +x entrypoint.sh.

Fix 4: CRLF line endings break the shebang

If the script was edited on Windows, CRLF turns #!/bin/sh into #!/bin/sh\r — the loader then looks for an interpreter literally named sh\r and fails. Convert to LF and keep it that way:

dos2unix entrypoint.sh          # convert CRLF -> LF

# keep shell scripts LF in git (.gitattributes):
*.sh text eol=lf

Debugging checklist

Frequently Asked Questions

What does 'exec format error' mean in Docker?

The kernel could not execute the container's binary because its format does not match the CPU. Almost always it is an architecture mismatch: an image built for amd64 (x86-64) running on an arm64 host like Apple Silicon, or vice versa. Less often, a script entrypoint is missing a shebang line.

How do I fix the architecture mismatch?

Run or build for the host's architecture. On Apple Silicon you can run an amd64 image under emulation with --platform linux/amd64, or better, pull/build a native arm64 image. When building, use docker buildx to produce a multi-arch image so it runs on both amd64 and arm64.

Why does it happen on an M1/M2/M3 Mac?

Apple Silicon is arm64. If an image (or a base image) only has an amd64 build, the binary inside doesn't match the CPU and fails with exec format error. Pull an arm64 variant, or pass --platform linux/amd64 to run it through emulation (slower but works).

Why does my CI image fail to run in production?

You likely built on one architecture and deploy on another — for example building on an Apple Silicon laptop (arm64) and deploying to an amd64 server. Build for the target with --platform linux/amd64, or publish a multi-arch image with docker buildx --platform linux/amd64,linux/arm64.

Can a shell script cause exec format error?

Yes. If your ENTRYPOINT or CMD runs a script with no shebang (no #!/bin/sh or #!/bin/bash first line), the kernel doesn't know how to execute it and reports exec format error. Add the shebang as the very first line, and make the script executable.

Could Windows line endings (CRLF) cause it?

Yes. A script saved with CRLF line endings turns the shebang into #!/bin/sh\r, so the loader looks for an interpreter named sh\r and fails. Convert the file to LF (dos2unix, or set .gitattributes to keep shell scripts LF) and rebuild the image.

More backend & build errors

Browse the full reference for Node.js, Python, Docker, and database errors — exact message, cause, and fix.

All Error References Docker: port already allocated Node build: OpenSSL error
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.