A container that works on your laptop exits immediately on the server with exec format error. The cause is almost always an architecture mismatch: the image was built for ARM (Apple Silicon Macs, Raspberry Pi) and the VPS runs x86-64 (amd64), or the reverse. A broken entrypoint script can produce the same message.
Before you start
- Docker on the server and the machine where you build images.
- The image name and tag that fails.
Compare architectures
On the server:
uname -mx86_64 means amd64; aarch64 means arm64. Then check the image:
docker image inspect myapp:latest --format '{{.Os}}/{{.Architecture}}'Docker also warns at start: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64).
Build for the server's platform
On an Apple Silicon Mac, build an amd64 image explicitly:
docker buildx build --platform linux/amd64 -t registry.example.com/myapp:1.4 --push .Or build a multi-architecture image that works everywhere:
docker buildx build --platform linux/amd64,linux/arm64 -t registry.example.com/myapp:1.4 --push .Multi-arch builds need --push (or a registry) because the local image store holds one platform at a time. Cross-building uses QEMU emulation and is slower; building in CI on amd64 runners avoids it.
Pull the right variant of a public image
Most official images are multi-arch and Docker picks the right one automatically. If a compose file or command forces a platform, remove it or set it correctly:
services:
app:
image: myorg/app:1.4
platform: linux/amd64If an image only exists for one architecture, you need a different image or must build it yourself.
When the architecture matches: entrypoint problems
If both are amd64 and you still get exec format error, the entrypoint script is the problem:
- Missing shebang: the first line of the script must be
#!/bin/shor#!/bin/bash. - Windows line endings: scripts edited on Windows contain CRLF; convert with
sed -i 's/\r$//' entrypoint.shor set* text=auto eol=lfin.gitattributes. - Shell not present: a
#!/bin/bashscript in an Alpine image without bash fails; use/bin/shor install bash. - Binary for another platform copied in: a downloaded tool or compiled binary inside the image must match the target architecture.
Run foreign images with emulation (testing only)
You can run ARM images on x86 with QEMU binfmt support:
docker run --privileged --rm tonistiigi/binfmt --install allEmulation is slow and unsuitable for production, but useful to test.
Check the fix
docker run --rm registry.example.com/myapp:1.4 uname -mIt should print the server's architecture and run without errors.
Exec format error FAQ
Why does it work on my Mac?
Docker Desktop on Apple Silicon builds arm64 images by default, matching the Mac but not a typical x86 VPS.
Are ARM VPS servers worth it?
They can be cost-effective, but every image you use must support arm64.
Does this affect Node.js or Python dependencies?
Yes: native modules compiled during build must be built for the target platform, which buildx handles when building inside the image.
