HTTP ステータスコード

登録済み HTTP ステータスコードを理由句と定義元 RFC 節つきで検索できる一覧表。1xx から 5xx のクラスで絞り込めます。

このレスポンスコードは結局何を意味するのか。 429 のような数字や gateway のような単語を入力して絞り込めます。クラス単位の絞り込みも可能です。各行にはコード、実際に通信で流れる理由句、そして定義元の仕様の節を表示します。

該当するコード
コード 理由句 定義元

HTTP ステータスコードの正しい読み方

契約を決めているのは先頭の数字

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 FoundI'm a teapot といった文字列が理由句です。HTTP/1.1 はステータス行でこれを送りますが、HTTP/2 と HTTP/3 は完全に廃止したため、現代の接続では数字だけが流れ理由句が存在しないことがよくあります。クライアントがこの文字列で分岐してはいけません。ログや生のトレースを読む人が、表を引かずに状況を把握するためだけに存在します。

見た目より制約が強いコードもあります。204 と 304 はメッセージボディを含んではならず、中間装置が勝手に付ければ不正なレスポンスになります。HEAD への応答はコードにかかわらずボディを持ちません。こうしたフレーミング規則が重要なのは、あるはずのない場所にボディがあると接続再利用の同期が崩れ、明確なエラーではなくリクエストをまたいだ奇妙なデータ混線として表面化するからです。

オープンソースに関する注記:バニラ JavaScript で実装。サードパーティライブラリは使用していません。

よくある質問

HTTP ステータスコードは全部でいくつありますか。
IANA に登録されているのは 5 クラス合計で 60 件強で、本表はそのすべてに加え、広く使われている WebDAV や拡張のコードも収録しています。レジストリは意図的に開かれており、だからこそクライアントは未知のコードをクラス数字で処理する必要があります。
恒久リダイレクトには 301 と 308 のどちらを使うべきですか。
古いクライアントに POST を GET へ変換させたいのでない限り 308 を使ってください。どちらもリソースが恒久的に移動したことを示しますが、メソッドとボディが保持されると保証するのは 308 だけです。通常のページ移転ならどちらでも構いません。
401 と 403 の違いは何ですか。
401 は未認証を意味し、レスポンスには認証方法を示す WWW-Authenticate ヘッダーが必要です。403 は認証は済んでいるが権限がないという意味です。ログインすれば解決するなら 401、アカウント自体に権限がないなら 403 が正解です。
418 I'm a teapot は本物のコードですか。
1998 年のエイプリルフール仕様「Hyper Text Coffee Pot Control Protocol」を定めた RFC 2324 に存在するという意味では本物です。IANA は 418 を他用途に使われないよう予約しています。HTTP 本体の一部ではありませんが、遊び心として実装しているフレームワークは複数あります。
クライアントが自動再試行すべきコードはどれですか。
408、429、および大半の 5xx は再試行してよく、Retry-After ヘッダーがあれば必ず従ってください。408 と 429 以外の 4xx は再試行しないでください。問題はリクエスト自体にあり、そのまま送り直しても同じ結果になります。
HTTP/2 のレスポンスに理由句がないのはなぜですか。
HTTP/2 と HTTP/3 は、そもそもクライアントが解析すべきでないという理由で理由句を通信フォーマットから削除しました。流れるのは数値コードだけです。HTTP/2 のレスポンスに理由句を表示するツールは、本表のような一覧からローカルに引いています。