Docker Python exec format error: wrong architecture or missing shebang (tested)

exec /usr/local/bin/python: exec format error means the container tried to start a file this machine can't execute. Below it is reproduced on an amd64 host with an arm64 image (at run time and in a RUN step) and with an entrypoint script that lacks a #! line, with the fix for each run.

1. Reproduce: wrong CPU architecture, and a script without #!

The files: a is a plain Python image, b starts through a shell script (once without a #! line, once with one), c has a RUN step:

# ---- a/Dockerfile
FROM python:3-alpine
CMD ["python", "-c", "import platform; print(platform.machine())"]
# ---- b/Dockerfile
FROM python:3-alpine
COPY start.sh start-fixed.sh /
ENTRYPOINT ["/start.sh"]
# ---- b/start.sh
echo "starting app"
exec python -c "print(42)"
# ---- b/start-fixed.sh
#!/bin/sh
echo "starting app"
exec python -c "print(42)"
# ---- c/Dockerfile
FROM python:3-alpine
RUN pip install -q six

run.sh, on an x86_64 (amd64) Linux host with no QEMU emulation registered:

#!/bin/sh
echo "host: $(uname -m)"
echo "== a: image built for arm64, run on this amd64 host"
docker build -q --platform linux/arm64 -t forever-ef410:arm a >/dev/null
docker image inspect --format '{{.Os}}/{{.Architecture}}' forever-ef410:arm
docker run --rm --name forever-ef410run forever-ef410:arm 2>&1
echo "exit code: $?"
echo "== a: same Dockerfile built for amd64"
docker build -q --platform linux/amd64 -t forever-ef410:amd a >/dev/null
docker run --rm --name forever-ef410run forever-ef410:amd 2>&1
echo "== b: ENTRYPOINT script without a #! line"
docker build -q -t forever-ef410:sh b >/dev/null
docker run --rm --name forever-ef410run forever-ef410:sh 2>&1
echo "exit code: $?"
echo "== b: script with #!/bin/sh"
docker run --rm --name forever-ef410run --entrypoint /start-fixed.sh forever-ef410:sh 2>&1

Output (Docker 29.8.1, python:3-alpine):

host: x86_64
== a: image built for arm64, run on this amd64 host
linux/arm64
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
exec /usr/local/bin/python: exec format error
exit code: 255
== a: same Dockerfile built for amd64
x86_64
== b: ENTRYPOINT script without a #! line
exec /start.sh: exec format error
exit code: 255
== b: script with #!/bin/sh
starting app
42

The same thing during a build, when a RUN step has to execute an arm64 binary:

#!/bin/sh
# a RUN step in a cross-platform build without emulation
docker build --platform linux/arm64 --progress=plain -t forever-ef410:c c > build.log 2>&1
echo "build exit code: $?"
grep -E "^#5 .*exec format|^ERROR" build.log
build exit code: 1
#5 0.320 exec /bin/sh: exec format error
ERROR: failed to build: failed to solve: process "/bin/sh -c pip install -q six" did not complete successfully: exit code: 255

2. What the error means

exec ...: exec format error is the Linux kernel refusing to start a file it can't run. In Python containers it is almost always one of two things:

3. Fixes for the architecture mismatch

Related: Docker Python ModuleNotFoundError, Docker pip externally-managed-environment, docker build failed.

Frequently asked questions

What causes exec format error in a Docker Python container?

Usually an image built for another CPU architecture (arm64 on amd64 or the reverse), or an entrypoint script without a #! shebang line.

How do I fix exec format error from an image built on a Mac M1/M2?

Rebuild for the server's platform with docker build --platform linux/amd64, or publish a multi-arch image with docker buildx build --platform linux/amd64,linux/arm64.

How do I check which architecture a Docker image is for?

docker image inspect --format '{{.Os}}/{{.Architecture}}' IMAGE

Written with AI assistance. Measured on 2026-10-23 with Docker 29.8.1 and python:3-alpine on an x86_64 Linux host. The scripts ran verbatim and the output was pasted unedited. PlainTables is our extension; Docker and Python are free.