エラーのシナリオ
このエラーは、システムアップデート(apt upgrade や yum update)の直後や、サーバー間でNginxの設定を手動で移行した後に発生することがあります。Nginxの起動やリロードを試みると失敗し、nginx -t を実行すると、次のような致命的なメッセージが表示されます。
nginx: [emerg] module "/etc/nginx/modules/ngx_http_geoip_module.so" is not binary compatible
nginx: configuration file /etc/nginx/nginx.conf test failed
このエラーはNginxの起動を妨げ、実質的にウェブサイトをオフラインにしてしまいます。これは、Nginxのコアバイナリと動的モジュール(.soファイル)の同期が取れていない場合に、GeoIP、Image Filter、PageSpeedなどのモジュールでよく発生します。
なぜバイナリ互換性が重要なのか
安定したプラグインやAPIを使用する一部のアプリケーションとは異なり、Nginxの動的モジュールはNginxバイナリと密接に結合されています。Nginxは**Application Binary Interface (ABI)**と呼ばれる内部構造を使用しています。Nginxがコンパイルされるたびに、そのシグネチャがモジュールに書き込まれます。
Nginxのバージョンを1.18.0から1.20.1にアップデートした際に、1.18.0ビルドの古い ngx_http_geoip_module.so ファイルをそのまま保持していると、メモリ構造が一致しなくなります。Nginxは load_module ディレクティブの実行中にこの不一致を検出し、メモリの破損や予期しないクラッシュを防ぐためにプロセスを停止します。
ステップ 1: バージョンの不一致を診断する
修正を適用する前に、実行中のNginxのバージョンを確認し、モジュールの期待されるバージョンと比較してください。
nginx -V
出力結果から --with-compat フラグを探します。Nginxが --with-compat 付きでコンパイルされている場合、バージョンの違いに対して多少の許容範囲がありますが、メジャーアップデートでは依然としてモジュールが動作しなくなることがあります。バージョン番号(例: 1.24.0)をメモしておいてください。
解決策 A: パッケージマネージャーによる同期(最も簡単)
apt や yum などのパッケージマネージャーを使用してNginxをインストールした場合、通常、モジュールのパッケージが保留されていたり、別のリポジトリからアップデートされたりしたことが原因で不一致が発生します。最も確実な修正方法は、現在のNginxバージョンに一致する特定のモジュールパッケージを再インストールすることです。
Ubuntu/Debianの場合:
# リポジトリリストの更新
sudo apt update
# Nginxコアと問題のあるモジュールの再インストール
sudo apt install --reinstall nginx-core libnginx-mod-http-geoip
CentOS/RHELの場合:
sudo yum reinstall nginx-mod-http-geoip
エラーが解消されない場合は、公式のNginxリポジトリ(nginx.org)を使用している一方で、モジュールがOSのデフォルトリポジトリからインストールされている(またはその逆)可能性があります。すべてのNginxコンポーネントが同じソースから提供されていることを確認してください。
解決策 B: モジュールの手動コンパイル(上級者向け)
カスタムビルドのNginxを使用している場合や、標準のリポジトリにないモジュールを使用している場合は、現在のNginxソースコードに対してモジュールをコンパイルする必要があります。
1. 一致するNginxソースをダウンロードする
nginx -v でバージョンを確認し、正確に一致するソースコードをダウンロードします。
wget http://nginx.org/download/nginx-$(nginx -v 2>&1 | cut -d '/' -f 2).tar.gz
tar -xzvf nginx-*.tar.gz
cd nginx-*
2. ビルド環境の設定
現在のNginxバイナリと全く同じ設定フラグを使用する必要があります。これらは nginx -V から取得できます。
# nginx -V から 'configure arguments' をコピーし、モジュールフラグを追加する
./configure --with-compat --add-dynamic-module=/path/to/module/source
3. モジュールのみをコンパイルする
フルビルドの make install を実行する代わりに、モジュールファイルのみを作成します。
make modules
4. 古い .so ファイルを置き換える
新しいモジュールは objs/ ディレクトリに作成されます。これをNginxのモジュールディレクトリにコピーしてください。
sudo cp objs/ngx_http_geoip_module.so /etc/nginx/modules/
# 権限の確認
sudo chmod 644 /etc/nginx/modules/ngx_http_geoip_module.so
確認
モジュールの置換やパッケージの再インストールが完了したら、サービスを再起動する前に必ず設定をテストしてください。
sudo nginx -t
syntax is ok および test is successful と表示されれば、安全にNginxを再起動できます。
sudo systemctl restart nginx
今後の再発を防ぐ方法
システムアップデートのたびに手動で対応しなくて済むよう、以下のベストプラクティスに従ってください。
- 公式リポジトリを使用する: Nginx.org リポジトリか、OSの安定リポジトリのどちらか一方のみを使用するようにしてください。それらを混在させることが、バイナリ互換性エラーの最大の原因です。
- Apt Pinning: Nginxを手動でコンパイルする場合、カスタムモジュールを更新せずにパッケージマネージャーがバイナリをアップデートしてしまうのを防ぐために、
apt-mark hold nginxを使用してください。 - 自動化: カスタムモジュールを使用する場合は、「ダウンロード -> 設定 -> モジュール作成」のプロセスをスクリプト化し、CI/CDやサーバープロビジョニングの一部として実行されるようにしてください。

