Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 10 min read

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 error
  • standard_init_linux.go: exec user process caused: exec format error inside a container.
  • A Kubernetes pod crash-looping with exec format error after a multi-arch image pull.
  • A script fails with Exec format error when run as ./script, but works as bash 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:

  1. CPU architecture mismatch. An amd64 ELF binary or container image running on arm64 hardware (Graviton, Apple Silicon, Ampere) or the reverse. This is the number-one cause today.
  2. Container image built for the wrong platform. docker build on an M-series Mac produced an arm64 image that then runs on amd64 nodes.
  3. 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.
  4. Corrupt or truncated binary. An interrupted download, a Git LFS pointer committed instead of the real file, or a partial scp.
  5. Wrong file entirely. A gzip/tar archive or text file with an executable bit set.
  6. 32-bit binary on a 64-bit-only kernel (or a foreign ABI with no binfmt_misc handler 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

  1. 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 with rustup target add aarch64-unknown-linux-gnu.

  2. 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 ....

  3. 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.

  4. Strip a BOM or CRLF from a script.

    sed -i '1s/^\xEF\xBB\xBF//' ./script.sh   # remove UTF-8 BOM
  5. Re-fetch a corrupt binary. Verify with a checksum before executing:

    sha256sum ./app        # compare against the published sum
  6. Register QEMU for foreign architectures (dev/CI only), if you genuinely need to run a non-native binary:

    Warning: This changes kernel binfmt_misc state 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 --platform explicitly 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/affinity so 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.

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.

Free download · 368-page PDF

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.