HTTP ステータスコード
登録済み HTTP ステータスコードを理由句と定義元 RFC 節つきで検索できる一覧表。1xx から 5xx のクラスで絞り込めます。
このレスポンスコードは結局何を意味するのか。 429 のような数字や gateway のような単語を入力して絞り込めます。クラス単位の絞り込みも可能です。各行にはコード、実際に通信で流れる理由句、そして定義元の仕様の節を表示します。
該当するステータスコードはありません。
登録済み HTTP ステータスコードを理由句と定義元 RFC 節つきで検索できる一覧表。1xx から 5xx のクラスで絞り込めます。
このレスポンスコードは結局何を意味するのか。 429 のような数字や gateway のような単語を入力して絞り込めます。クラス単位の絞り込みも可能です。各行にはコード、実際に通信で流れる理由句、そして定義元の仕様の節を表示します。
該当するステータスコードはありません。
HTTP レスポンスはすべて 3 桁の数字で始まりますが、クライアントが理解を義務づけられているのは先頭 1 桁だけです。RFC 9110 は明確に述べています。未知の 499 を受け取ったクライアントは、それを 400 とまったく同じように扱わなければなりません。意味を決めるのはクラスであり、残り 2 桁はそれを細分化するにすぎないからです。この規則があるおかげでプロトコルは拡張し続けられます。2005 年に書かれたプロキシは、法的検閲が何かを知らなくても 451 を正しく中継できます。
5 つのクラスは「次に誰が責任を負うか」できれいに分かれます。1xx は暫定応答で、本当の答えはこれから届きます。2xx は成功で、クライアントはそこで終えてかまいません。3xx はリダイレクトを返すので、別の場所へ再試行します。4xx はリクエスト側の問題なので、そのまま送り直しても再び失敗します。5xx はサーバー側の問題なので、同じリクエストでも再試行すれば成功する可能性があります。リトライ処理を個別のコードではなくクラスで分岐すべきなのはこのためです。503 の再試行は妥当ですが、403 の再試行はバグです。
301 と 308、302 と 307 の違いは趣味の問題ではありません。古い方の組は、リダイレクトを追う際にクライアントが POST を GET へ書き換えることを許しており、ブラウザは実際にそうしてきました。新しい方の組はその書き換えを禁じ、メソッドもボディも保持します。フォームのエンドポイントを 301 で移すと、一部のクライアントは送信を黙って GET に変え、ペイロードを捨ててしまいます。冪等でないものには 308 か 307 を使ってください。
401 と 403 も同様に取り違えられます。401 は「認証されていない」という意味で、レスポンスには再試行方法を示す WWW-Authenticate ヘッダーを必ず含めなければなりません。403 は「あなたが誰かは分かったうえで拒否する」という意味です。チャレンジヘッダーのない 401 は仕様違反ですし、ログインを忘れただけのユーザーに 403 を返すと原因追跡が格段に難しくなります。
4xx にはもう一つ有用な対があります。400 と 422 です。400 はリクエストをそもそも解析できなかった、つまり構文が壊れている状態。422 は構文は正しく解析できたが内容が検証に通らなかった状態です。この 2 つを分けるだけで、API 利用者にとって不透明な失敗が対処可能な情報に変わります。
コードの横にある Not Found や I'm a teapot といった文字列が理由句です。HTTP/1.1 はステータス行でこれを送りますが、HTTP/2 と HTTP/3 は完全に廃止したため、現代の接続では数字だけが流れ理由句が存在しないことがよくあります。クライアントがこの文字列で分岐してはいけません。ログや生のトレースを読む人が、表を引かずに状況を把握するためだけに存在します。
見た目より制約が強いコードもあります。204 と 304 はメッセージボディを含んではならず、中間装置が勝手に付ければ不正なレスポンスになります。HEAD への応答はコードにかかわらずボディを持ちません。こうしたフレーミング規則が重要なのは、あるはずのない場所にボディがあると接続再利用の同期が崩れ、明確なエラーではなくリクエストをまたいだ奇妙なデータ混線として表面化するからです。