Nginx 431: Request Header Fields Too Large の修正 (JWT と肥大化した Cookie)

beginner Nginx2026-07-06| Linux (Ubuntu, CentOS, Debian) 上の Nginx、Docker Nginx イメージ、OpenResty

Error Message

431 Request Header Fields Too Large
#nginx#431#large-client-header-buffers#headers#jwt#cookie

TL;DR: クイック修正

ヘッダーが Nginx のデフォルト設定に対して大きすぎると、431 エラーが発生します。これは、設定ファイルのヘッダーバッファサイズを増やすことで修正できます。Nginx の設定ファイル(通常は /etc/nginx/nginx.conf または /etc/nginx/sites-available/ 内のサイト別ファイル)を開き、httpserver、または 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 が独自のエラーを返します。

Related Error Notes