Linux で 'bash: ./app: cannot execute binary file: Exec format error' を修正する

beginner🐧 Linux2026-03-22| Linux(Ubuntu、Debian、CentOS、Alpine)— 全ディストリビューション対応;ARM と x86_64 のアーキテクチャ不一致、Docker コンテナ、クロスコンパイルされたバイナリ

Error Message

bash: ./app: cannot execute binary file: Exec format error
#bash#バイナリ#アーキテクチャ#arm#x86#exec-format

何が起きたのか

バイナリをダウンロードしたり、プログラムをコンパイルしたり、別のマシンから実行ファイルをコピーしたりして、実行したところ以下のエラーが表示された:

bash: ./app: cannot execute binary file: Exec format error

シェルはファイルを見つけ、実行ビットが設定されていることも確認した。しかしカーネルは実行を完全に拒否した。この拒否はほぼ必ず3つのいずれかが原因だ:バイナリが異なるCPUアーキテクチャ向けである、ファイルが実際には実行ファイルではない、またはELFインタープリタが存在しない。原因ごとに異なる対処が必要となる。診断を省略すると、間違った方法に20分を費やすことになる。

ステップ1 — ファイルの実体を確認する

バイナリに対して file コマンドを実行する。どのアーキテクチャおよびフォーマット向けにビルドされているかを最速で確認できる方法だ:

file ./app

出力例とその意味:

# x86_64マシン上のARMバイナリ — アーキテクチャの不一致
./app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)

# x86_64バイナリ — 最新のLinuxマシンの多くで動作するはず
./app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV)

# ELFではない — 誰かがリネームしたWindowsの.exeかもしれない
./app: PE32+ executable (console) x86-64, for MS Windows

# シェバンのないシェルスクリプト
./app: ASCII text

自分のマシンのアーキテクチャを確認する:

uname -m
# x86_64   → Intel/AMD 64ビット
# aarch64  → ARM 64ビット(Apple Silicon、Raspberry Pi 4、AWS Graviton)
# armv7l   → ARM 32ビット(旧型Raspberry Pi)

file の出力と uname -m が一致しない場合、それが原因だ。

ステップ2 — 正確な原因を特定する

原因A:アーキテクチャの不一致(最も一般的)

x86_64マシン上でARMバイナリを実行しているか、またはその逆のケースだ。以下の4つの状況が確実にこれを引き起こす:

  • アーキテクチャのラベルを確認せずにインターネットからビルド済みバイナリを取得した
  • Apple Silicon Mac(aarch64)でビルドし、x86_64サーバーにバイナリをコピーした
  • ホストとは異なるアーキテクチャをターゲットにしたベースイメージのDockerコンテナ内にいる
  • クロスコンパイルしたが、ターゲットを正しく設定しなかった

原因B:ファイル形式の誤り(ELFではない)

WindowsのPE実行ファイル(.exe)、macOSのMach-Oバイナリ、シェバン行のないプレーンテキストスクリプトはすべて同じエラーを生成する。ファイルの拡張子は関係ない — Linuxは名前ではなくマジックバイトを使用する。

原因C:32ビットライブラリなしの64ビットシステム上の32ビットバイナリ

アーキテクチャが一致するバイナリでもここで失敗することがある。64ビットLinuxシステム上の32ビットx86 ELFは lib32 パッケージのインストールが必要だ:

file ./app
# ./app: ELF 32-bit LSB executable, Intel 80386

ステップ3 — 適切な修正を適用する

修正A:自分のアーキテクチャに合った正しいバイナリを入手する

ビルド済みリリースをダウンロードする場合は、プラットフォームに合った適切なアーカイブを選ぶ。多くのプロジェクトでは予測可能な命名規則を使用している:

# x86_64 / amd64
app-linux-amd64
app-linux-x86_64

# ARM 64ビット
app-linux-arm64
app-linux-aarch64

# ARM 32ビット
app-linux-armv7
app-linux-arm

ダウンロードし、file で確認してから実行する:

curl -LO https://example.com/releases/app-linux-amd64
chmod +x app-linux-amd64
file ./app-linux-amd64
./app-linux-amd64

修正B:ターゲットアーキテクチャ向けに再コンパイルする

ソースコードがあるなら、ターゲットマシン上で直接コンパイルするか、適切なターゲットフラグを指定してクロスコンパイルする。

Goはクロスコンパイルを非常に簡単にしている — 必要なのは2つの環境変数だけだ:

# Linux x86_64向けにコンパイル
GOOS=linux GOARCH=amd64 go build -o app-linux-amd64 .

# Linux ARM64向けにコンパイル
GOOS=linux GOARCH=arm64 go build -o app-linux-arm64 .

GCCを使ったCの場合は、まずクロスコンパイラのツールチェーンをインストールする:

# ARMクロスコンパイラをインストール
sudo apt install gcc-aarch64-linux-gnu

# ARM64向けにコンパイル
aarch64-linux-gnu-gcc -o app-arm64 main.c

修正C:QEMUエミュレーションを追加する(再コンパイルなしで異種アーキテクチャのバイナリを実行)

再コンパイルできない場合もある — バイナリがクローズドソースだったり、簡単なテストだけが必要だったりする場合だ。QEMUユーザーモードエミュレーションを使えば、ソースに触れることなく異種アーキテクチャのバイナリを実行できる:

# QEMUユーザーモードエミュレーションをインストール
sudo apt install qemu-user qemu-user-static

# x86_64上でARM64バイナリを実行
qemu-aarch64 ./app-arm64

# カーネルがQEMUを自動的に呼び出すようbinfmt_miscハンドラを登録
sudo apt install binfmt-support
sudo update-binfmts --enable qemu-aarch64

binfmtハンドラが登録されると、プレフィックスが不要になる:

./app-arm64  # QEMUを経由して透過的に実行される

修正D:32ビットELFバイナリのために32ビットサポートをインストールする

# Debian/Ubuntu
sudo apt install lib32z1 lib32stdc++6

# CentOS/RHEL
sudo yum install glibc.i686 libstdc++.i686

修正E:スクリプトの場合はシェバンを追加する

file がプレーンテキストを出力する場合、そのファイルにはインタープリタ行が欠けている。最初の行を確認する:

head -1 ./app

先頭に #! がない場合は追加する:

#!/usr/bin/env bash
# スクリプトの残り...

その後、実行ビットを再設定して実行する:

chmod +x ./app
./app

Docker特有のシナリオ

Dockerコンテナはこのエラーが最も人を驚かせる場所だ。x86_64 ホスト上で arm64 イメージを取得したり、M1 MacでビルドしてクラウドVMにデプロイしたりすると、気づかないうちに誤ったアーキテクチャが生成される。リリース前に確認しよう:

# イメージのアーキテクチャを確認
docker inspect --format='{{.Architecture}}' myimage

# 特定のプラットフォームを明示的に取得
docker pull --platform linux/amd64 myimage

# 特定のプラットフォーム向けにビルド
docker buildx build --platform linux/amd64 -t myimage .

AWS GravitonやRaspberry PiなどのARMサーバーにデプロイする場合は、ビルドステップで --platform linux/arm64 を設定し、後付けではなくCIパイプラインの一部として組み込もう。

修正が有効かどうかを確認する

# 1. アーキテクチャが自分のマシンと一致することを確認
file ./app
uname -m

# 2. バイナリを実行
./app

# 3. 終了コードを確認 — 0は成功を意味する
echo $?

アーキテクチャを修正してもまだ失敗する場合は、不足している共有ライブラリが次の容疑者だ:

ldd ./app
# 以下のような行を探す:
# libssl.so.1.1 => not found

not found の各エントリは、インストールが必要なパッケージに対応している。

クイックリファレンス

  • アーキテクチャの不一致 → ターゲットアーキテクチャ向けの正しいバイナリをダウンロードするか再コンパイルする
  • 異種アーキテクチャのバイナリを実行する必要がある → QEMUユーザーモード + binfmt_miscをインストールする
  • 64ビットシステム上の32ビットバイナリlib32 パッケージをインストールする
  • シェバンのないスクリプト → 最初の行に #!/usr/bin/env bash を追加する
  • Windows/macOSのバイナリ → Linuxビルドが必要、それ以外の方法はない

まず file ./app を実行しよう。常に。2秒の出力が、上記5つの修正のどれが適用されるかを正確に教えてくれる。

Related Error Notes