guides / check-binary-architecture scenariosupdated 2026-10-25 readelf -h ./app

How to check whether a binary is 32-bit or 64-bit (and for which CPU)

2026-10-25 By luckyray Debian 12 · Ubuntu 24.04 · Alpine 3.20

The question sounds trivial until you are holding a binary that will not start. Word size and instruction set are two separate facts recorded in the ELF header, and mixing them up sends people installing multilib packages for a problem that is actually a CPU mismatch.

The one command that answers both

$ file ./agent
./agent: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked,
         interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, stripped

Read it left to right and you have everything:

FragmentMeans
ELF 64-bitEI_CLASS — pointer and offset width
LSBlittle endian (MSB would be big endian)
executablee_type — ET_EXEC; shared object or pie executable would appear otherwise
ARM aarch64e_machine — the instruction set
dynamically linkedhas PT_INTERP and DT_NEEDED
interpreter /lib/ld-linux-aarch64.so.1which libc family the loader expects
strippedno .symtab

If file is not installed, or you want the raw fields, readelf -h is the authoritative source:

$ readelf -h ./agent | grep -E 'Class|Data|OS/ABI|Type|Machine|Flags'
  Class:                             ELF64
  Data:                              2's complement, little endian
  OS/ABI:                            UNIX - System V
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           AArch64
  Flags:                             0x0

What “64-bit” does not tell you

Class and machine are independent. A 64-bit file can be EM_X86_64, EM_AARCH64, EM_RISCV, EM_PPC64 or several others. Two binaries that both report ELF 64-bit will refuse to run on each other’s machines.

The mapping that matters in practice:

file sayse_machineRuns on
x86-6462Intel/AMD 64-bit hosts
ARM aarch64183ARM 64-bit (Pi 4/5, Graviton, Apple Silicon VMs)
Intel 80386332-bit x86, or 64-bit hosts with multilib
ARM, EABI54032-bit ARM (Pi 2/3 in 32-bit mode, many embedded boards)
RISC-V243RISC-V 64
IBM S/39022s390x mainframes — and this one is big endian

That last row is the trap: comparing uname -m output without checking endianness gives a confident and wrong answer.

Compare against the host correctly

$ uname -m
x86_64

$ getconf LONG_BIT
64

uname -m reports the kernel’s architecture. getconf LONG_BIT reports the userland’s word size. On a 64-bit kernel with a 32-bit userland they disagree, and that disagreement explains why a 64-bit binary can fail on a machine whose uname -m says x86_64.

For containers there is a third place to look:

$ docker image inspect myapp:latest --format '{{.Architecture}} / {{.Os}}'
arm64 / linux

If that disagrees with your host, you have the cause of the failure before you ever run the binary.

When the answers disagree

BinaryHostResult
ELF32 i386x86_64 + multilibruns
ELF32 i386x86_64, no multilibmissing ld-linux.so.2
ELF64 AArch64x86_64Exec format error
ELF64 s390xx86_64Exec format error — wrong endianness and machine
ELF64 x86-64x86_64runs, subject to GLIBC symbol versions

A one-liner for a directory full of binaries

When you are triaging a release tarball rather than a single file:

find . -type f -exec file {} + | grep -E 'ELF (32|64)-bit' | sort | uniq -c | sort -rn

That collapses to something like “12 × ELF 64-bit x86-64, 3 × ELF 64-bit AArch64” in one line, which is usually the answer to “did the build pipeline emit the wrong architecture again”.

Doing it without a shell

If the machine with the problem is the one you cannot install binutils on — a hardened jump host, a scratch container, a customer VPN — the ELF Inspector reads class, endianness and e_machine in a browser tab and reports them in the same vocabulary as readelf. The Compatibility Checker goes one step further and compares those fields against a target platform you select, including the GLIBC symbol versions the binary requires.

Related: Exec format error for the failure this diagnosis usually explains, and wrong ELF class for the 32/64 mix-up at link time.


Every command in this guide was run against the distribution named in the output. If your output differs, the mechanism section explains why — and the ELF Inspector shows the same fields without needing a shell.

Related

guides
  1. How to tell whether a binary is stripped (and what it costs you) What strip removes, what it leaves behind, how to confirm it with file and readelf, and how to get usable stack traces back from a stripped production binary.
  2. How to check PIE, RELRO, NX and stack canaries without installing checksec Five readelf commands that reproduce a checksec report, what each field really proves, and the cases where the answer is misleading.
  3. cannot execute binary file: Exec format error — causes and fixes Why Linux refuses to run a binary with Exec format error, how to confirm the cause in three commands, and the five fixes that actually apply.