根本原因:バージョンの不一致
最新の開発マシンからレガシーな本番サーバーに新しいバイナリを移動した際に、この壁に突き当たることが多いでしょう。エラーの内容は単純明快です。アプリケーションが、そこには存在しないバージョンのGNU Cライブラリ(glibc)を探しているのです。
/lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found
Linuxのライブラリには厳格なルールがあります。それは「後方互換性はあるが、前方互換性はない」ということです。古いシステム向けにビルドされたアプリは新しいシステムでも動作します。しかし、新しいシステム(glibc 2.34を使用するUbuntu 22.04など)でビルドされたアプリは、古いシステム(glibc 2.31を使用するUbuntu 20.04など)では動作しません。
まず、システムのバージョンを確認する
修正作業に入る前に、サーバーで実際に動作しているバージョンを確認しましょう。次のコマンドを実行します。
ldd --version
出力が2.31や2.27であれば、バージョンの乖離が確認できたことになります。また、バイナリが具体的にどのシンボルを要求しているかを確認することもできます。
strings /path/to/your/app | grep GLIBC_2.34
ここで一致するものがあれば、そのバイナリはバージョン2.34以降を要求するようにハードコードされていることが証明されます。
解決策1:Dockerでコンテナ化する
Dockerは、コンテナが独自の環境を持つため、多くの場合最も簡単な解決策となります。ホストが古いOSであっても、アプリにglibc 2.34が必要な場合は、Ubuntu 22.04のような最新のベースイメージを使用するだけです。ホストのバージョンに関係なく、コンテナ内のライブラリが処理を肩代わりしてくれます。
# Dockerfileの例
FROM ubuntu:22.04
COPY ./your-app /usr/local/bin/your-app
RUN chmod +x /usr/local/bin/your-app
ENTRYPOINT ["/usr/local/bin/your-app"]
このアプローチでは、コードを変更することなく、ホストの古いライブラリを完全にバイパスできます。
解決策2:ターゲット環境でローカルビルドする
ソースコードにアクセスできる場合、最もクリーンで「ネイティブ」な解決策は、古いサーバー上でアプリを直接再コンパイルすることです。ローカルでビルドすることで、コンパイラは利用可能な古いglibcバージョン(例:2.31)に対して自動的にリンクします。
# 標準的なビルド例
g++ main.cpp -o my_app
# リンクの確認
ldd my_app | grep libc.so.6
これにより、バイナリが特定の環境に完全に最適化されます。
解決策3:「古くビルドする」戦略
プロの開発チームは「サポートする最も古いシステムでビルドする」というルールを採用しています。Ubuntu 20.04と22.04の両方をサポートするには、20.04でビルドを行います。これにより、要求バージョンの低いバイナリが生成され、新しいシステムでも動作するようになります。
GitHub Actionsを使用している場合は、ランナーを古いイメージに固定します。
# GitHub Actionsのスニペット
jobs:
build:
runs-on: ubuntu-20.04 # 互換性を高めるためglibc 2.31をターゲットにする
steps:
- uses: actions/checkout@v4
- run: make build
解決策4:Muslで静的リンクにする
GoやRustのような言語では、静的リンクが可能です。これにより、必要なライブラリコードがすべてバイナリファイルに直接埋め込まれます。glibcの代わりにmusl-libcを使用することで、システムのlibc.so.6のバージョンに依存しない「どこでも動く」バイナリを作成できます。
# Rust: ポータブルなバイナリのためにmuslをターゲットにする
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
その結果、ファイルサイズはわずかに大きくなりますが、glibcのバージョンエラーの影響を全く受けなくなります。
警告:システムを壊さないでください
本番環境で/lib/x86_64-linux-gnu/libc.so.6を手動で置き換えたり、ソースコードからglibcを強制的にアップグレードしたりしないでください。ほぼすべての主要コマンド(ls、sudo、ssh)はこの特定のファイルに依存しています。ここでのミスは即座にカーネルパニックを引き起こし、システムが起動すらしない状態になります。
検証手順
修正を適用した後、以下のチェックを行って動作を確認してください。
- 動的リンクの確認:
ldd your-appを実行します。すべてのエントリが「not found」ではなく、有効なファイルパスを指している必要があります。 - スモークテストの実行:
./your-app --helpを実行し、リンカーエラーでクラッシュせずに起動することを確認します。 - シンボルの検査:
nm your-app | grep GLIBCを使用して、バイナリが現在参照している正確なバージョンを確認します。

