1. 質問とコンテキスト
ログイン後、ページは CDN、ロードバランサー、サービスメッシュを経由して API に到達します。一部のユーザーが 431 Request Header Fields Too Large を受信しますが、シークレットウィンドウや curl では動作します。ステータスのセマンティクス、ホップごとの診断、修復、およびリリース検証について説明してください。HTTP/1.1 または HTTP/2 が使用される可能性があり、ログに完全な Cookie や認可値を含めることはできないと想定します。
2. 面接官が評価するポイント
- 肥大化したヘッダーブロック全体と単一の肥大化したフィールドを区別し、431 がリクエスト処理前のクライアントエラーレスポンスであることを理解していること。
- アプリケーションサーバーのみを変更するのではなく、CDN、ゲートウェイ、プロキシ、アプリケーション全体で測定すること。
- Cookie の肥大化、重複した Set-Cookie 値、長いトークン、および転送ヘッダーが原因の可能性が高いと認識すること。
- セキュリティを低下させることなく、クライアントの状態を削減し、認証情報をローテーションし、サイズに関するオブザーバビリティを追加すること。
3. 最初に明確にすべき質問
- どのホップが 431 を生成したか、またレスポンスヘッダー、サーバー ID、またはエッジログでそれを特定できるか?
- 失敗したリクエストの合計ヘッダーバイト数、最大のフィールド、およびプロトコルは何か?
- ブラウザは古い Cookie、サブドメインをまたぐ Cookie、または増加するセッションデータを送信しているか?
- 各レイヤーは集計ヘッダー、単一フィールド、リクエストライン、またはバッファを制限しているか、また HTTP/2 のデコード制限は存在するか?
4. 30秒での回答
431 は、リクエストヘッダーの合計または特定のフィールドが許可された制限を超えたため、サーバーがリクエストを拒否したことを意味します。RFC 6585 では単一のユニバーサルなバイト制限を定義していません。クライアントからエッジ、ゲートウェイ、プロキシ、アプリケーションに至るまで、マスキングされた合計サイズと最大のフィールドを測定し、431 を返す最初のホップを見つけます。ブラウザのみが失敗する場合は、制限を引き上げる前に Cookie、重複した Set-Cookie、および認可を検査します。クライアントの状態を削除し、トークンを短縮するかサーバー側のセッション参照に置き換え、古い Cookie を期限切れにし、ホップ間で予算を調整します。キャパシティとサービス妨害(DoS)の分析を行った後にのみ制限を引き上げます。
5. ステップごとの回答
ステップ 1: ステータスと送信ホップの確認
通過したノード、プロトコル、レスポンスヘッダー、および相関 ID を記録します。オリジンへの直接、CDN を迂回、ゲートウェイ経由、およびマスキングされたブラウザヘッダーを使用した最小限のリクエストをリプレイし、どこで最初に 431 が発生するかを比較します。一部のプロキシは同様の制限に対して 400 または 494 などのベンダー固有のコードを使用するため、ステータスをノードのログおよび設定と組み合わせます。
ステップ 2: ヘッダーのバイト数測定
すべてのフィールドのエンコードされたバイト長を計算し、合計リクエストヘッダー、リクエストライン、最大のフィールド、およびフィールド数を記録します。文字数はバイト数とは異なり、圧縮された HTTP/2 ヘッダーブロックはデコードされたフィールドの合計ではありません。ログにはフィールド名、長さ、ハッシュプレフィックス、およびリクエスト ID のみを保持し、Cookie の値、ベアラートークン、または完全な Referer は絶対に記録しないでください。
ステップ 3: ブラウザ固有の原因の特定
Cookie は主要な容疑者です。複数のパスやサブドメインでの同名 Cookie、Cookie に保存されたユーザーデータ、および各レスポンスで新しい値が追加されることにより、以降のリクエストが肥大化します。Set-Cookie の Domain、Path、有効期限、および削除動作を検査します。古い名前が特定のパスでのみ上書きされるのではなく、実際に期限切れになっていることを確認します。認可トークンは短く保ち、変更可能なデータは制御されたサーバー側のセッションまたはセキュアなストアに配置します。
ステップ 4: プロキシホップと HTTP/2 の考慮
転送によって X-Forwarded-*、トレーシング、認証フィールドが追加される一方で、各ホップには異なる合計制限、フィールドごとの制限、バッファ制限が設定されている場合があります。予算を設定契約として公開し、最も小さい制限をクライアント設計の上限として使用します。HTTP/2 はトランスポート圧縮に HPACK を使用しますが、エンドポイントは引き続きフィールドをデコードして制限を適用します。圧縮率はビジネスヘッダーが安全であることを証明するものではありません。アプリケーションが何も受信していないときにゲートウェイの拒否についてアラートを発報します。
ステップ 5: 修復策と防御策の選択
重複した Cookie を削除し、セッション内容を削減し、状態をサーバー側に移動し、推測不可能な短い参照のみを送信します。トークンの長さ、ローテーション、および失効ポリシーを設定し、未知または異常に大きなカスタムフィールドを拒否します。テナントごとまたはルートごとの合理的な予算を設定し、解析メモリ、同時実行性、およびサービス妨害コストを確認した後にのみ制限を引き上げます。
6. 模範解答
431 を返す最初のホップを特定し、マスキング後に失敗したリクエスト(合計ヘッダーバイト数、最大のフィールド、リクエストライン、フィールド数、HTTP バージョン)を測定します。ブラウザのみの失敗は、まず重複またはサブドメイン間の Cookie、増加するセッションデータ、または認可の長さを指し示しています。CDN、ロードバランサー、またはメッシュがより早い段階で拒否する可能性があるため、オリジンの制限のみを変更することは安全ではありません。古い Cookie を期限切れにし、クライアントの状態を最小限に抑え、サーバー側のセッション参照を使用し、ホップ間の予算を調整します。HTTP/2 のトランスポート圧縮は、デコード後の制限を排除するものではありません。本番テレメトリでは、認証情報を保存することなく、長さとハッシュプレフィックスのみを保存しながら、ホップおよびフィールド名ごとにサイズのパーセンタイルを集計します。
7. よくある間違い
- ブラウザの Cookie のみをクリアすること: 一時的なものに過ぎない可能性があります。セッター、Domain、Path、および有効期限のロジックをトレースして、重複した
Set-Cookieの根本原因を取り除きます。 - 431 が常に 8 KB を意味すると想定すること: RFC 6585 には普遍的な制限は規定されていません。各レイヤーを検査し、バイト数を測定してください。
- オリジンの制限のみを引き上げること: エッジやゲートウェイが依然として最初に拒否する可能性があり、解析コストも増加します。予算を調整し、キャパシティを評価してください。
- 完全なリクエストヘッダーをログに記録すること: これにより Cookie やトークンが露出します。名前、長さ、ハッシュプレフィックス、相関 ID のみを保持してください。
- HTTP/2 圧縮によって制限がなくなると想定すること: エンドポイントはフィールドをデコードして制限を適用します。トランスポート圧縮はデコード後のサイズとは別にテストしてください。
8. フォローアップの質問と回答
フォローアップ 1: なぜ curl は動作し、ブラウザは失敗するのですか?
ブラウザはドメインに一致するすべての Cookie、認証、およびトラッキングヘッダーを自動的に送信しますが、curl は通常より小さくなります。ブラウザのリクエストをエクスポートし、二分探索でフィールドを削除しながら各ホップを測定して、クライアントのコンテンツとプロキシの制限を切り分けます。
フォローアップ 2: JWT を Cookie に保存できますか?
可能ですが、すべてのリクエストがトークンのバイトコストを負担し、複数の Cookie が制限を超える可能性があります。クライアント側には短い参照または最小限のクレームのみを保持し、変更可能なデータと失効処理はサーバー側に保存して、長さとローテーションの予算を適用します。
フォローアップ 3: 制限の引き上げが許容されるのはどのような場合ですか?
要件が本物であり、すべてのホップが解析メモリと同時実行性を吸収でき、キャパシティ、タイムアウト、サービス妨害テストを通過した場合にのみ許容されます。サイズテレメトリ、レート制限、およびロールバック設定を維持します。上限を引き上げることだけが解決策ではありません。