Linux Error: Exec format error — Cause, Fix, and Troubleshooting Guide
How to fix the Linux 'Exec format error' (ENOEXEC): wrong CPU architecture, missing shebang, corrupt binaries, and multi-arch container images explained.
- #linux
- #troubleshooting
- #containers
- #kernel
Summary
Exec format error is the kernel’s ENOEXEC (errno 8): the loader looked at a file you asked it to execute and could not recognize it as runnable on this machine. The overwhelming cause in production is an architecture mismatch — an x86_64 binary on arm64 (or vice versa), which is now everyday breakage on Apple Silicon, AWS Graviton, and Raspberry Pi fleets. A missing or malformed shebang on a script, or a truncated/corrupt binary, produces the same message.
Common Symptoms
bash: ./app: cannot execute binary file: Exec format errorstandard_init_linux.go: exec user process caused: exec format errorinside a container.- A Kubernetes pod crash-looping with
exec format errorafter a multi-arch image pull. - A script fails with
Exec format errorwhen run as./script, but works asbash script. - A cross-compiled binary runs on the build host but not on the target device.
Most Likely Causes of the ‘Exec format error’ Error
Production causes, most common first:
- CPU architecture mismatch. An
amd64ELF binary or container image running onarm64hardware (Graviton, Apple Silicon, Ampere) or the reverse. This is the number-one cause today. - Container image built for the wrong platform.
docker buildon an M-series Mac produced anarm64image that then runs onamd64nodes. - Missing or malformed shebang. A script with no
#!line, or a#!not on the very first byte of the file, is handed to the ELF loader, which rejects it. - Corrupt or truncated binary. An interrupted download, a Git LFS pointer committed instead of the real file, or a partial
scp. - Wrong file entirely. A gzip/tar archive or text file with an executable bit set.
- 32-bit binary on a 64-bit-only kernel (or a foreign ABI with no
binfmt_mischandler registered).
Quick Triage
# What is this file, really?
file ./app
# What architecture is the host?
uname -m
# First bytes — ELF magic (7f 45 4c 46) or a shebang?
head -c 16 ./app | hexdump -C
If file says ELF 64-bit ... x86-64 and uname -m says aarch64, you have your answer.
Diagnostic Commands
file ./app
Classifies the file: ELF architecture, script, archive, or data. The single most useful command here.
uname -m
The host machine architecture: x86_64, aarch64, armv7l. Compare against what file reports.
readelf -h ./app | grep -E 'Machine|Class|Type'
Reads the ELF header directly: Machine shows the target CPU (AArch64, Advanced Micro Devices X86-64), Class shows 32- vs 64-bit.
head -c 4 ./app | hexdump -C
A valid ELF starts with 7f 45 4c 46 (.ELF). A script starts with 23 21 (#!). Anything else (e.g. 1f 8b = gzip) means it is not an executable at all.
head -c 2 ./script.sh | hexdump -C
For scripts, confirm the shebang is the literal first two bytes. A leading UTF-8 BOM (ef bb bf) before #! breaks it.
docker image inspect <image> --format '{{.Architecture}}'
The architecture baked into a container image. Compare with uname -m on the node.
Inside a running container, cat /proc/sys/fs/binfmt_misc/status and ls /proc/sys/fs/binfmt_misc/ reveal whether QEMU emulation handlers are registered for foreign binaries.
Fix / Remediation
-
Get the right architecture binary. Re-download or rebuild for the host arch reported by
uname -m. For Go:GOARCH=arm64 go build. For Rust: add the target withrustup target add aarch64-unknown-linux-gnu. -
Build multi-arch container images. Use Buildx so the manifest serves both arches:
docker buildx build --platform linux/amd64,linux/arm64 -t myrepo/app:tag --push .To force a single target at run time:
docker run --platform linux/amd64 .... -
Fix a missing/broken shebang. Add
#!/usr/bin/env bash(or the correct interpreter) as the literal first line, or just invoke the interpreter explicitly:bash ./script.sh. -
Strip a BOM or CRLF from a script.
sed -i '1s/^\xEF\xBB\xBF//' ./script.sh # remove UTF-8 BOM -
Re-fetch a corrupt binary. Verify with a checksum before executing:
sha256sum ./app # compare against the published sum -
Register QEMU for foreign architectures (dev/CI only), if you genuinely need to run a non-native binary:
Warning: This changes kernel
binfmt_miscstate host-wide. Do not do this on production nodes to “work around” a wrong-arch deploy — fix the build instead.docker run --privileged --rm tonistiigi/binfmt --install all
Validation
file ./app # arch now matches the host
readelf -h ./app | grep Machine # Machine line matches uname -m
./app --version # actually runs
For containers, confirm the served arch:
docker run --rm myrepo/app:tag uname -m
Prevention
- Pin
--platformexplicitly in Dockerfiles and CI, and build multi-arch manifests with Buildx. - Add a checksum verification step to any pipeline that downloads binaries.
- Store scripts with LF line endings and no BOM; enforce it with
.gitattributes(*.sh text eol=lf). - On mixed x86/arm fleets, label nodes by arch and set pod
nodeSelector/affinityso images land on matching hardware. - Keep a smoke test (
./app --version) as the last build stage so a wrong-arch artifact fails the build, not production.
Related Errors
- Linux Error: bad interpreter: No such file or directory
- Linux Error: No such file or directory (when the file exists)
- Linux Error: cannot open shared object file
- Linux Error: Permission denied
- Kubernetes Error: exec format error
Final Notes
Exec format error almost always means “this file is not the shape of program this CPU can run.” Let file, readelf -h, and uname -m settle the architecture question in seconds, and check the first bytes with hexdump -C when a script is involved. On modern arm/x86 mixed infrastructure, treat every Exec format error as an architecture question until proven otherwise.
Want faster Linux incident response? Use DevOps AI Toolkit to turn production errors into clear diagnostics, remediation steps, and reusable runbooks.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.