Fix "cannot execute binary file: Exec format error" on Linux

Quick fix

Compare the file's architecture with your machine's. If they differ, download the build for your CPU.

file ./program
uname -m

x86-64 needs an x86_64 machine; ARM aarch64 needs aarch64. If the file is a script, make sure its first line is a shebang such as #!/bin/bash.

What the error means

When a program starts, the kernel's execve() call inspects the first bytes of the file to decide how to run it: an ELF binary for the running CPU, or a script starting with #!. If the file is neither, execve() fails with ENOEXEC, which is printed as "Exec format error". From an interactive shell it looks like this:

$ ./node_exporter
bash: ./node_exporter: cannot execute binary file: Exec format error

Other programs call execve() directly and word it differently:

exec /usr/local/bin/docker-entrypoint.sh: exec format error
standard_init_linux.go:228: exec user process caused: exec format error
myapp.service: Failed to execute /opt/myapp/run: Exec format error
myapp.service: Main process exited, code=exited, status=203/EXEC

The file exists and is executable; the kernel just does not know how to run it.

Identify your case

file ./program
uname -m
head -c 64 ./program | od -c | head -3
file saysMeaningGo to
ELF ... ARM aarch64 on an x86_64 machine (or x86-64 on aarch64)Wrong CPU architectureCause 1
Bourne-Again shell script, ASCII text with no #! lineScript without a shebangCause 2
PE32+ executable ... MS Windows or Mach-OWindows or macOS binaryCause 3
HTML document, gzip compressed data, Zip archive, ELF ... relocatableNot a program at allCause 4

Cause 1: wrong CPU architecture (most common)

Binaries are compiled for one instruction set. An x86_64 (amd64) build will not run on a Raspberry Pi, an ARM laptop, an AWS Graviton server or an Ampere box, and an aarch64 (arm64) build will not run on a normal PC. Release pages usually offer several files; the names to look for:

uname -mDownload namesTypical hardware
x86_64amd64, x86_64, x64, linux64Most desktops, laptops and cloud VMs
aarch64arm64, aarch64Raspberry Pi 4/5 with 64-bit OS, ARM laptops and servers
armv7larmhf, armv732-bit Raspberry Pi OS, older boards
riscv64riscv64RISC-V boards

Download the matching build. If you install with a package manager instead (apt, dnf, pacman, zypper), it always picks the right architecture for you, which is a good reason to prefer packaged software. On Debian-based systems dpkg --print-architecture shows the package architecture, which can differ from the kernel's (a 64-bit kernel with a 32-bit armhf userland on older Raspberry Pi OS, for example). See the Raspberry Pi OS reference for which image you are running.

Docker images built on the wrong platform

The Docker variant almost always means the image was built on an Apple Silicon Mac (arm64) and deployed to an x86_64 server, or built on a PC and pulled onto an ARM host. Check and rebuild for the target:

docker image inspect myimage --format '{{.Os}}/{{.Architecture}}'
docker buildx build --platform linux/amd64 -t myimage .
# multi-arch image (push to a registry)
docker buildx build --platform linux/amd64,linux/arm64 -t registry.example.com/myimage --push .

More on Docker setup is in the Docker installation guide.

Running foreign binaries with QEMU

If no native build exists, QEMU user-mode emulation plus the kernel's binfmt_misc lets the kernel hand foreign ELF files to an emulator automatically. Expect it to be several times slower than native.

# Ubuntu, Debian, Mint
sudo apt install qemu-user-static binfmt-support
# Fedora
sudo dnf install qemu-user-static
# Arch
sudo pacman -S qemu-user-static qemu-user-static-binfmt
# check registered formats
ls /proc/sys/fs/binfmt_misc/

Dynamically linked foreign binaries also need that architecture's libraries; statically linked tools (many Go and Rust releases) just work.

Cause 2: a script without a shebang

When you type ./script in bash and the kernel returns ENOEXEC, bash quietly runs the file as a shell script itself, so a script with no #! line appears to work in a terminal. systemd, cron, Docker's ENTRYPOINT/CMD in exec form, sudo and programs using exec() do not have that fallback, so the same script fails there with "Exec format error".

Make sure the very first bytes of the file are #! followed by the interpreter:

head -1 entrypoint.sh
# should print something like
#!/bin/sh

Things that break this: a blank line or comment above the shebang, leading spaces, or a UTF-8 byte order mark (od -c shows 357 273 277 first). If the shebang is there but the error says "No such file or directory" instead, you probably have Windows line endings: see /bin/bash^M: bad interpreter.

Cause 3: a Windows or macOS binary

Linux executes ELF files only. A .exe (PE format) or a macOS binary (Mach-O) gives this error. Look for a Linux build of the program; for Windows-only software, Wine or Steam's Proton may run it. A Linux binary that is merely called something like tool-darwin-arm64 is still the macOS build: pick the file with linux in its name.

Cause 4: the file is not an executable

  • Failed download: curl or wget saved an HTML error or login page. file says HTML document. Download again, following redirects with curl -LO, and verify the checksum.
  • Still archived: gzip compressed data, XZ compressed data or Zip archive. Extract it first (tar xf file.tar.gz, unzip file.zip) and run the binary inside.
  • Object file: ELF 64-bit LSB relocatable is a .o from gcc -c, not a linked program. Link it with gcc file.o -o program.
  • Truncated or corrupted copy: file says data. Copy or download again and compare sha256sum with the published value.

Distro-specific notes

  • Ubuntu, Debian, Mint: package names for QEMU binfmt have shifted across releases; if qemu-user-static is not found, try apt search qemu-user. Multiarch (dpkg --add-architecture arm64) installs foreign libraries for emulated binaries.
  • Fedora: qemu-user-static registers its binfmt handlers through systemd-binfmt.service automatically.
  • Arch: the handlers are in the separate qemu-user-static-binfmt package; restart systemd-binfmt after installing.
  • openSUSE: user-mode emulators come in qemu-linux-user; check zypper search qemu for your release.
  • 32-bit x86 programs on a 64-bit PC do not cause this error. If one fails with "No such file or directory", its 32-bit loader and libraries are missing; see shared library not found.

How to prevent it

  • Install from your distro's repositories, Flatpak or the vendor's package repository when possible; they select the architecture for you.
  • In scripts that download releases, map uname -m to the right asset name instead of hard-coding amd64.
  • Start every script with a shebang on line 1 and mark it executable (chmod +x); if you get "Permission denied" instead, see fixing bash: Permission denied.
  • Build container images with an explicit --platform in CI.

Frequently asked questions

How do I check if a binary is for ARM or x86?

Run file ./program. It prints the format and CPU, for example ELF 64-bit LSB executable, x86-64 or ARM aarch64. Compare with uname -m, which shows your CPU architecture.

Why do I get exec format error in Docker?

The image was built for a different CPU architecture than the host, typically an arm64 image built on an Apple Silicon Mac running on an x86_64 server, or the reverse. Build with docker buildx build --platform linux/amd64,linux/arm64, or make sure the entrypoint script has a #! shebang.

Can I run an x86_64 program on a Raspberry Pi or ARM laptop?

Only through emulation. Install QEMU user-mode emulation with binfmt support and the kernel will run foreign binaries transparently, but slowly. A native ARM build is always better.

Can Linux run a Windows .exe or a macOS binary?

Not directly; both use formats the Linux kernel does not execute (PE and Mach-O). Windows programs can run through Wine or Proton; macOS binaries cannot run on Linux.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.