何が起きたか
すでに十数ドメインが設定済みのNginxサーバーに新しいバーチャルホストを追加しようとしていた。設定を検証するために nginx -t を実行したところ、こんなエラーが返ってきた:
nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: configuration file /etc/nginx/nginx.conf test failed
Nginxはリロードを拒否し、新しいサイトは起動しないまま。エラーログには追加情報が一切なく、その1行だけ。nginx.conf の2行を修正すれば解決するのだが、どの2行をなぜ変更するのかを理解するには少し調査が必要だった。
根本原因
Nginxはすべての server_name の値を高速ルックアップ用のハッシュテーブルに格納する。そのテーブルの各バケットはデフォルトで64バイトに設定されている。ドメイン名、あるいはすべてのドメイン名の合計サイズが64バイトのバケットに収まらない場合、Nginxは起動時にテーブルを構築できず、このエラーを投げる。
よくある原因:
some-very-long-subdomain.client-company-name.example.comのような長いドメイン名(50文字超えも珍しくない)*.subdomain.example.comのようなワイルドカードエントリ- 1つの
server_nameディレクティブに大量のエイリアスを詰め込んでいる場合 - 新しいバーチャルホストを追加したことで、ハッシュの合計サイズが上限を超えた場合
デバッグ手順
まず、問題を引き起こしている設定を特定する:
nginx -T 2>&1 | grep server_name
これでマージされた設定全体が出力される。異常に長い名前や、エイリアスが大量に詰め込まれたサーバーブロックを探す。次に設定テストを実行し、エラーをよく読む:
sudo nginx -t
エラーに bucket_size: 64 と表示されていれば128に増やす。すでに bucket_size: 128 と表示されていれば、さらに倍の256にする。
最も長いサーバー名をすばやく見つけたい場合は、次を実行する:
grep -r 'server_name' /etc/nginx/sites-enabled/ | awk '{print length, $0}' | sort -rn | head -5
60〜70文字に達している名前が犯人だ。50文字未満であれば、デフォルトの64バイトのバケットサイズで通常は問題ない。
修正方法
/etc/nginx/nginx.conf を開き、http ブロック内に以下を追加または更新する:
http {
# 長いサーバー名に対応するためハッシュバケットサイズを増やす
server_names_hash_bucket_size 128;
server_names_hash_max_size 512;
# ... 残りの設定
}
この2つのディレクティブはそれぞれ別の問題を解決する:
server_names_hash_bucket_size— 各バケットのサイズを制御する。2の累乗である必要がある:64 → 128 → 256。1つのドメイン名が長すぎて収まらない場合に増やす。server_names_hash_max_size— バケットの総数を制御する。デフォルトは512。数百のドメインをホストしている場合にのみ関係する — ほとんどの場合は変更不要。
このエラーが発生する典型的なサーバーでは、server_names_hash_bucket_size 128 だけで十分だ。最初から256に設定しておいてもコストはなく、将来のドメイン追加に備えた余裕が生まれる。
修正を適用する
# まず設定をテストする — 必ず実行
sudo nginx -t
# テストが通ったらリロード
sudo systemctl reload nginx
確認
正常なテスト結果はこのようになる:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
次にサービスが起動しており、新しいバーチャルホストが応答することを確認する:
sudo systemctl status nginx
curl -I http://your-new-domain.com
リモートやロードバランサー越しにデバッグしている場合は、ワーカープロセスを直接確認する:
ps aux | grep nginx
マスタープロセスとワーカープロセスが少なくとも1つずつ表示されるはずだ。マスターのみでワーカーがいない場合は、まだ何かの読み込みに失敗している。
エッジケース
128に設定してもエラーが続く場合
エラーに bucket_size: 128 と表示される場合、本当に巨大なドメイン名が存在する。256に直接ジャンプする:
server_names_hash_bucket_size 256;
2の累乗のみ有効。192のような値は機能しない — Nginxが暗黙のうちに切り捨てるか、別のエラーを投げる。
設定が別のインクルードファイルにある場合
ディストリビューションによっては nginx.conf を複数のインクルードに分割していることがある。ディレクティブが server ブロックではなく、http ブロックの中に記述されていることを確認する:
nginx -T 2>&1 | grep -A2 -B2 'server_names_hash'
誤って server ブロック内に記述してしまうと、そのディレクティブは暗黙的に無視される — エラーが出続け、原因がわからず1時間無駄にすることになる。
予防策
最近は、バーチャルホストを設定する前に、新規Nginxインストール時に必ずこの2行を追加するようにしている:
server_names_hash_bucket_size 128;
server_names_hash_max_size 1024;
10秒で済む。これで、誰かが staging-api.long-client-name.internal.example.com のようなドメインを追加した深夜2時のリロード失敗を防げる。
複数のNginxサーバーを管理していてデプロイ前に設定を検証したい場合、nginx -t -c /path/to/test.conf でデプロイ前にローカルコピーをテストできる。テストした設定がサーバーに正確に反映されているかバイト単位で確認するには、toolcraft.app のHash Generatorを使ったSHA-256チェックを実行している — ブラウザ内で動作し、ファイルはアップロードされない。
得られた教訓
systemctl reload nginxの前には必ずnginx -tを実行する。壊れた設定でリロードすると無音で失敗し、古い設定がそのまま動き続け、警告も一切出ない。- 64バイトのデフォルトは短い名前には十分だ。しかし誰かが
portal.north-america-region.client.example.comのようなサブドメインを追加した瞬間に上限を超える。最初から128に設定しておくべきだ。 - エラーメッセージは少し誤解を招く。
bucket_sizeを指しているが、300以上のドメインをホストしている場合は実際にはmax_sizeを調整する必要がある。両方を確認すること。 - このエラーは設定の読み込み時、つまり起動またはリロード時にのみ発生する。何ヶ月も問題なく動いていたサーバーが、1つの設定変更後に突然リロードを拒否することがある。それまでは何も壊れていなかった — 新しい名前がただ閾値を超えただけだ。

