TL;DR: クイック修正
ヘッダーが Nginx のデフォルト設定に対して大きすぎると、431 エラーが発生します。これは、設定ファイルのヘッダーバッファサイズを増やすことで修正できます。Nginx の設定ファイル(通常は /etc/nginx/nginx.conf または /etc/nginx/sites-available/ 内のサイト別ファイル)を開き、http、server、または location ブロックに以下のディレクティブを追加します。
http {
# バッファサイズを 16k または 32k に増やす
large_client_header_buffers 4 16k;
# ... 残りの設定
}
変更を保存した後、構文を確認してサービスをリロードします:
sudo nginx -t
sudo systemctl reload nginx
このエラーが発生する理由
431 Request Header Fields Too Large ステータスは、ブラウザやモバイルアプリなどのクライアントから送信された HTTP ヘッダーが、サーバーが処理するには大きすぎることを意味します。HTTP 仕様では厳密な制限は設定されていませんが、Nginx はメモリ枯渇攻撃からサーバーを保護するために、デフォルトで小さなバッファを使用しています。
この問題は、以下のようなケースで発生しやすくなります:
- **肥大化した JWT トークン:** 多くのカスタムクレームや大きなメタデータオブジェクトを含むトークン。
- **Cookie の蓄積:** アプリやサードパーティツール(Google Analytics や HubSpot など)が数十の Cookie を設定すると、`Cookie` ヘッダーの合計が簡単に 8KB を超えることがあります。
- **エンタープライズ認証:** 企業の SSO 環境で使用される複雑な認証ヘッダー。
Nginx は、client_header_buffer_size(初期リクエストライン用)と large_client_header_buffers を通じてこれらの制限を管理します。431 エラーの原因は、ほとんどの場合後者です。
詳細な修正方法
1. グローバル設定
グローバル設定を更新することは、すべてのサイトにわたって問題を修正する最も速い方法です。これは、重い認証トラフィックを処理する専用の API ゲートウェイでは標準的な方法です。
# メイン設定を編集
sudo nano /etc/nginx/nginx.conf
http ブロック内にディレクティブを挿入します:
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# '4' はバッファの数、'16k' は各バッファのサイズです
large_client_header_buffers 4 16k;
# ...
}
2. 特定のサーバーブロックでの修正
重い Auth0 トークンを使用するフロントエンドなど、特定のアプリケーションのみがエラーを発生させている場合は、その特定の仮想ホストにのみ修正を適用します。
server {
listen 443 ssl;
server_name api.example.com;
# このドメインにのみ適用
large_client_header_buffers 4 32k;
location / {
proxy_pass http://backend_upstream;
}
}
3. 適切なバッファサイズの選択
ほとんどの Nginx ビルドのデフォルトは 4 8k です。これは、Nginx がヘッダー用に 8KB のバッファを 4 つ割り当てることを意味します。ユーザーロールが詰め込まれた JWT のように、1 つのヘッダーが 10KB に達すると、8KB のスロットに収まらないためリクエストは失敗します。
- **16k:** 大きな JWT を使用するほとんどのアプリに最適な設定です。
- **32k:** レガシーシステムや非常に重い Cookie データがある場合に使用します。
- **64k:** 絶対に必要な場合のみ使用してください。32KB 以上が必要になることは稀です。
修正の検証方法
Nginx をリロードしたら、エラーが解消されたことを確認します。ブラウザを操作せずに、curl を使用して巨大なヘッダーをシミュレートできます。
以下のコマンドを実行して、10KB のダミーヘッダーをサーバーに送信します:
# 10KB のダミーヘッダーを作成
LONG_HEADER=$(printf 'X-Custom-Header: %.0sA' {1..10000})
curl -I -H "$LONG_HEADER" http://localhost/
結果: 431 エラーの代わりに HTTP/1.1 200 OK またはリダイレクトが表示されるはずです。
セキュリティと副作用
メモリと安全性のバランス
割り当てる各バッファはメモリを消費します。8KB から 32KB への引き上げは 8GB の RAM を搭載したサーバーに悪影響を与えませんが、1MB に設定すると危険な場合があります。攻撃者は、巨大なヘッダーを持つ数千の同時接続を開くことで、理論上サーバーのメモリを枯渇させることができます。問題を解決できる最小限のサイズにとどめてください。
ブラウザの制限
ブラウザ側の制限も忘れないでください。Chrome や Firefox には独自の制限があり、多くの場合 1 つのヘッダーにつき 8KB から 16KB 程度です。Nginx 側で問題がなくてもユーザーにエラーが表示される場合は、Cookie からデータを削除し、リクエストボディ (POST) や localStorage に移動することを検討してください。
アップストリームロードバランサー
アプリが AWS ALB や Cloudflare の背後にある場合は、それらのサービスが新しいヘッダーサイズをサポートしていることを確認してください。たとえば Cloudflare には、すべてのヘッダーの合計に対して 32KB という厳密な制限があります。これを超えると、リクエストが Nginx に到達する前に Cloudflare が独自のエラーを返します。

