The image was built for a different CPU architecture
CommonAn image built on an amd64 laptop or CI runner is run on an arm64 node, such as Graviton or Apple Silicon, or the reverse, and the image has no build for the node's architecture. The kernel's ELF loader rejects the binary as the wrong architecture.
Confirm
docker image inspect --format '{{.Os}}/{{.Architecture}}' <image>
kubectl get nodes -L kubernetes.io/archDifferent architectures. The image's field is metadata only, so for a binary copied into the image, check the binary itself with file
Fix
- Build a multi-platform image so each node pulls the matching build: docker buildx build --platform linux/amd64,linux/arm64 and push it.
- For compiled languages, cross-compile in the Dockerfile instead of emulating, for example Go with GOOS and GOARCH set from the TARGETOS and TARGETARCH build arguments.
- As a stopgap in Kubernetes, pin the pod to matching nodes with nodeSelector: kubernetes.io/arch: amd64. It hides the problem rather than fixing it.
docker buildx imagetools inspect <image> docker buildx build --platform linux/amd64,linux/arm64 -t <image> --push .
The first lists the platforms an image in the registry was built for. The second builds both and pushes them. Docker Desktop and Engine 29 use the containerd image store, which can also hold a multi-platform image locally; the docker-container driver cannot, so push from there.