Fix: Docker "exec /usr/bin/sh: exec format error"

Updated Jun 2026 · Tested on Docker 24+, Apple Silicon, Linux amd64, AWS Graviton

Advertisement

Your image builds fine, the container starts, and then it dies instantly with:

exec /usr/bin/sh: exec format error

(The exact binary varies — you might see /bin/sh, /usr/bin/bash, or a docker-entrypoint.sh.) In almost every case this means one thing: you’re running an image built for a different CPU architecture than your machine. An ARM image on an x86 host, or an x86 image on an ARM host. Here’s how to confirm it and fix it for good.

Why this happens

A compiled binary is built for a specific CPU architecture. An amd64 (x86_64) binary literally cannot run on an arm64 CPU and vice versa — the instruction formats are incompatible. When Docker tries to execute the shell or entrypoint inside such a container, the kernel doesn’t recognise the binary format and returns “exec format error.”

This used to be rare. It’s now everywhere, because ARM machines have gone mainstream:

  • Apple Silicon Macs (M1/M2/M3/M4) are arm64
  • AWS Graviton instances are arm64
  • Raspberry Pi (v3+) is arm64
  • Most servers and CI runners are still amd64

So the classic trap is: you build an image on your M-series Mac (arm64), push it, and it fails on an amd64 server — or you pull an arm64-only image onto an x86 box.

Step 1 — Confirm it’s an architecture mismatch

Don’t guess. Check both sides.

Your host’s architecture:

uname -m

x86_64 means amd64; aarch64 or arm64 means ARM.

The image’s architecture:

docker image inspect your-image | grep -i architecture

Or, for a remote image, list every platform it supports:

docker buildx imagetools inspect your-image:tag

If the image’s architecture doesn’t include your host’s, that’s your problem confirmed. Now pick the fix that matches your situation.

Fix 1 — Pull the right variant (running someone else’s image)

If the image is public and does publish a build for your architecture, Docker usually picks it automatically. When it doesn’t, force it:

docker run --platform linux/amd64 your-image
# or
docker run --platform linux/arm64 your-image

You can set this as a default for a session so you don’t repeat it:

export DOCKER_DEFAULT_PLATFORM=linux/amd64

Fix 2 — Build for multiple architectures (your own image)

This is the permanent fix when you control the image. Use buildx to build for both architectures at once, so the image runs anywhere:

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag youruser/yourimage:v1 \
  --push \
  .

A few things to know:

  • --push is required for multi-platform builds. The result is a manifest list that points to one image per architecture, and Docker’s classic local store can’t hold that — it has to go to a registry. (To keep one locally for testing, build a single platform with --load instead.)
  • Set up buildx once if you haven’t: docker buildx create --use creates a builder that supports multi-platform.
  • For a single-architecture local test build:
docker buildx build --platform linux/arm64 --tag myapp:test --load .

Handling architecture-specific steps in a Dockerfile

If your Dockerfile downloads a binary or compiles code, it needs to know the target architecture. buildx sets TARGETARCH automatically:

FROM alpine:3.19
ARG TARGETARCH
RUN case "$TARGETARCH" in \
      amd64) ARCH="x86_64" ;; \
      arm64) ARCH="aarch64" ;; \
      *) echo "Unsupported: $TARGETARCH" && exit 1 ;; \
    esac && \
    wget "https://example.com/tool-${ARCH}" -O /usr/local/bin/tool

This builds the correct variant for each platform in the same multi-arch build.

Fix 3 — Emulate with QEMU (last resort)

When you genuinely must run a foreign-architecture image and can’t rebuild it, QEMU emulates the other CPU. Register the emulators once:

docker run --privileged --rm tonistiigi/binfmt --install all

After that, Docker can run amd64 images on ARM and vice versa.

The other cause: a bad shebang

Architecture is the usual culprit, but “exec format error” can also come from a script with a missing or malformed shebang. If a container tries to execute a shell script directly and the first line isn’t a valid interpreter line, the kernel doesn’t know how to run it.

Check that scripts start with a proper shebang on the very first line, with no leading spaces or blank lines and no Windows line endings:

#!/bin/sh

If you edited the script on Windows, CRLF line endings can corrupt the shebang. Convert it:

sed -i 's/\r$//' your-script.sh

And make sure it’s executable: chmod +x your-script.sh.

Which fix to use

SituationFix
Running a public image, wrong arch pulled--platform (Fix 1)
Your own image, must run on amd64 + arm64buildx multi-arch (Fix 2)
Must run a foreign-arch image, can’t rebuildQEMU (Fix 3)
Script fails with format error, arch is fineFix the shebang / line endings

Avoiding it going forward

If you build images that others (or your own servers) will run, make multi-architecture builds the default. A single buildx command covering linux/amd64,linux/arm64 means nobody hits this error regardless of whether they’re on an M-series Mac, a Graviton instance, or an x86 server. Wire it into your CI pipeline and the problem disappears permanently.

FAQ

Why does my image build fine but fail at runtime? Building and running are separate steps. The image can build for one architecture and only fail when a host with a different architecture tries to execute its binaries. The build succeeding tells you nothing about which CPUs it can run on.

I’m on an Apple Silicon Mac — why does my image break on the server? Your Mac is arm64, so a default build produces an arm64 image. A typical amd64 server can’t run it. Build with buildx --platform linux/amd64,linux/arm64 so it runs on both.

Does --platform linux/amd64 make an arm64-only image work on amd64? No. --platform selects an existing variant; it can’t create one. If no amd64 build exists, you must rebuild it (Fix 2) or emulate (Fix 3).

How do I check what architectures an image supports? docker buildx imagetools inspect your-image:tag lists every platform in the image’s manifest.

For more container and DevOps references, browse the DevOps topic.

Advertisement