exec format error
Fix "exec format error": check the image with docker inspect, then run docker buildx build --platform linux/amd64. Covers multi-arch images and CI.
standard_init_linux.go:228: exec user process caused: exec format error
Incident Overview
Fix "exec format error": check the image with docker inspect, then run docker buildx build --platform linux/amd64. Covers multi-arch images and CI.
medium fix·7 min read
By Vishvesh Patel·DevOps Engineer·Updated 16 September 2026
standard_init_linux.go:228: exec user process caused: exec format error exec /app/server: exec format error no matching manifest for linux/amd64 in the manifest list entries
Do this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• Compare the image architecture against the machine
arm64 against x86_64, or the reverse, is the whole bug. An image built on an Apple Silicon Mac and run on an ordinary cloud node is by far the most common path to this.
• On Kubernetes, check what architectures the nodes are
A mixed-architecture cluster schedules the Pod anywhere, so the same image works on some nodes and fails on others, which reads as a flaky deploy rather than a build problem.
• Build for every architecture you actually run on
A multi-arch manifest fixes it for every consumer at once. If you only ever deploy to one target, docker build --platform linux/amd64 is enough.
exec format error means the kernel was handed a binary it cannot execute. In containers this is almost always a CPU architecture mismatch. An arm64 image running on amd64 hardware, or the reverse.
It became common the moment Apple Silicon Macs did. Build an image on an M-series Mac, push it, deploy to an amd64 server, and this is what you get.
docker image inspect myapp:1.0 --format '{{.Architecture}}/{{.Os}}' && uname -mConfirm the architecture
Check what the image actually is:
Then check what the target expects:
arm64 image, amd64 node. That is the whole problem.
For an image in a registry, inspect the manifest without pulling it:
A multi-architecture image lists several entries. A single-architecture one lists exactly one, and if that one is not your target, you have found it.
docker image inspect myapp:1.0 --format '{{.Architecture}}/{{.Os}}'The three variants of this error
The third is the friendlier one, because the registry noticed before anything ran. The first two mean the image was pulled successfully and only failed when the kernel tried to execute the binary.
Fix 1: Build for the target platform
If you only need one architecture, name it explicitly:
On Apple Silicon this uses emulation, so the build is noticeably slower, often several times slower for a compile-heavy image. It works, and for occasional builds it is the simplest answer.
Note that --platform on docker build requires BuildKit, which is the default in current Docker versions.
docker build --platform linux/amd64 -t myapp:1.0 . docker push myapp:1.0
Fix 2: Build multi-architecture with buildx
The better answer for anything shared. One image reference serves both architectures, and each host pulls the variant it needs.
--push is required for multi-platform builds. The local Docker image store cannot hold a multi-arch manifest, so --load only works for a single platform. Trying to build multi-arch without pushing fails with a message about the docker exporter not supporting multiple platforms, which is confusing until you know why.
Verify the result:
# One-time setup docker buildx create --name multiarch --use docker buildx inspect --bootstrap # Build and push both at once docker buildx build \ --platform linux/amd64,linux/arm64 \ -t ghcr.io/acme/payments-api:1.4.2 \ --push .
Fix 3: Pin the base image platform in the Dockerfile
For a Dockerfile that must always produce one architecture regardless of where it is built:
Use this sparingly. It defeats multi-arch builds entirely, since every stage is forced to one platform, which is occasionally what you want and usually not.
A more useful pattern uses BuildKit's automatic platform arguments, so a cross-compiling build knows both what it is running on and what it is building for:
The build stage runs natively on the builder, fast, and cross-compiles to the target. For Go and Rust this avoids emulation entirely and is dramatically quicker than the --platform approach.
FROM --platform=linux/amd64 node:22-alpine
In CI
GitHub Actions and GitLab runners are amd64 by default, so an image built there runs on amd64 nodes and fails on Graviton or Apple Silicon.
setup-qemu-action provides the emulation needed to build the non-native architecture. Expect the build to take meaningfully longer, which is a real argument for cross-compilation where your language supports it.
# GitHub Actions
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/acme/payments-api:${{ github.sha }}On Kubernetes with mixed nodes
A cluster with both amd64 and Graviton nodes will schedule Pods onto either, so a single-architecture image fails intermittently. Working on some nodes and crash-looping on others, which is a genuinely confusing symptom.
Either publish multi-arch images, or constrain scheduling while you sort it out:
The node selector is a workaround. Multi-arch images are the fix, and they are what let you adopt Graviton's roughly 20% cost saving without maintaining two pipelines.
spec:
nodeSelector:
kubernetes.io/arch: amd64Not an architecture problem?
Occasionally exec format error means something else:
A script with no shebang. A file executed directly needs #!/bin/sh on the first line, or the kernel has no idea how to run it.
Windows line endings. A script saved with CRLF has \r at the end of the shebang, so the kernel looks for an interpreter literally named /bin/sh\r. The resulting error sometimes appears as no such file or directory naming a path that clearly exists, which is maddening.
Add a .gitattributes with *.sh text eol=lf to stop it recurring on mixed-OS teams.
file entrypoint.sh # entrypoint.sh: POSIX shell script, ASCII text, with CRLF line terminators sed -i 's/\r$//' entrypoint.sh
A checklist
Frequently Asked Questions
What causes "exec format error" in Docker?
The kernel was given a binary compiled for a different CPU architecture. Most often an arm64 image built on an Apple Silicon Mac being run on amd64 servers. Confirm with docker image inspect <image> --format '{{.Architecture}}' and compare against your target, which is uname -m locally or the architecture field on your Kubernetes nodes. The fix is building for the right platform, or publishing a multi-architecture image that serves both.
How do I build a Docker image for amd64 on an Apple Silicon Mac?
docker build --platform linux/amd64 -t myapp:1.0 . builds for the target using emulation, which works but is noticeably slower, sometimes several times slower for compile-heavy images. For anything shared, use docker buildx build --platform linux/amd64,linux/arm64 --push to publish a multi-architecture image instead, so each host pulls the variant it needs and you are not choosing one architecture at the expense of the other.
Why does my multi-platform buildx build fail without --push?
Because the local Docker image store cannot hold a multi-architecture manifest. It stores one image per tag. --load therefore only works when building a single platform. A multi-platform build must go straight to a registry with --push, which is where a manifest list can exist. If you need the image locally for testing, build just your own platform with --load, and build both with --push when publishing.
What does "no matching manifest for linux/amd64" mean?
The registry holds the image but has no build for your platform. It is the same architecture mismatch caught earlier, at pull time rather than at execution, which is why the message is more helpful than a bare exec format error. Check what the image actually publishes with docker manifest inspect <image>, and either build the missing architecture or pick a base image that publishes it. Most official images are multi-arch; smaller third-party ones frequently are not.
How do I handle mixed amd64 and Graviton nodes in Kubernetes?
Publish multi-architecture images, which lets any node pull the variant it needs and is what makes adopting Graviton's roughly 20% saving practical. Until then, a single-architecture image on a mixed cluster fails intermittently. Running on some nodes and crash-looping on others as the scheduler places Pods, which is a confusing symptom. As a stopgap, constrain scheduling with nodeSelector: kubernetes.io/arch: amd64, but treat that as temporary rather than the solution.
I get exec format error but the architecture matches. What else causes it?
Two things. A script executed directly with no shebang line, so the kernel does not know which interpreter to use. Add #!/bin/sh as the first line. Or Windows CRLF line endings, where the trailing \r makes the kernel look for an interpreter literally named /bin/sh\r; this sometimes surfaces as no such file or directory naming a path that obviously exists. Check with file script.sh, fix with sed -i 's/\r$//', and add *.sh text eol=lf to .gitattributes.
Reference and practice
Learn the underlying concept
Other Docker errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.