多数のバーチャルホスト設定時にNginxの「could not build the server_names_hash」エラーを修正する

intermediate Nginx2026-05-08| Ubuntu 20.04/22.04、Debian 11/12、CentOS 7/8など任意のLinuxディストリビューション上のNginx 1.14以降

Error Message

fatal: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
#nginx#server_name#config-error#vhost

何が起きたか

すでに十数ドメインが設定済みの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つの設定変更後に突然リロードを拒否することがある。それまでは何も壊れていなかった — 新しい名前がただ閾値を超えただけだ。

Related Error Notes