
HTTP ステータスコードの設計思想 — RFC 9110 の 5 クラス分類と歴史的コードの運命
Web 開発者なら毎日目にする 200 OK, 404 Not Found, 500 Internal Server Error。しかし「なぜ 3 桁なのか」「なぜ先頭の数字でクラスが決まるのか」「418 I'm a teapot は本当に公式なのか」と問われると、即答できる人は少ないのではないでしょうか。本記事では RFC 9110 (HTTP Semantics, 2022) を一次資料に、HTTP ステータスコードの設計思想、30 年にわたる仕様の変遷、そして個性的なコードの物語を整理します。
HTTP/0.9 にはステータスコードがなかった
1991 年、Tim Berners-Lee が設計した最初の HTTP (後に HTTP/0.9 と呼ばれる) は、驚くほどシンプルなプロトコルでした。リクエストは GET /path の 1 行だけ。レスポンスはヘッダもステータス行もなく、HTML 本文がそのまま返されるだけでした。
RFC 1945 (HTTP/1.0, 1996) は HTTP/0.9 のレスポンス形式を以下のように定義しています:
Simple-Response = [ Entity-Body ]
つまり「成功したかどうか」を知る手段がなかったのです。ページが存在しなければ接続が切れるだけ。エラーメッセージも、リダイレクトも、キャッシュ制御もありませんでした。
RFC 1945 (1996) — ステータスコードの誕生
Tim Berners-Lee、Roy Fielding、Henrik Frystyk が著した RFC 1945 (May 1996) で HTTP/1.0 が定義され、ここで初めてステータスコードが登場します。レスポンスの先頭行が Status-Line になりました:
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
例: HTTP/1.0 200 OK
なぜ 3 桁なのか? これは FTP (RFC 959, 1985) や SMTP (RFC 821, 1982) など、先行するインターネットプロトコルの慣例を踏襲しています。3 桁の数字は人間が読みやすく、先頭 1 桁でクラス分類できるという実用的な理由です。
HTTP/1.0 で定義されたステータスコードは 16 個でした。200, 201, 202, 204, 301, 302, 304, 400, 401, 403, 404, 500, 501, 502, 503 — 現在でもすべて現役です。
5 クラス分類 — 先頭の数字が意味を決める
RFC 9110 §15 では、ステータスコードの先頭桁による 5 つのクラスを定義しています:
| クラス | 範囲 | 意味 | 代表例 |
|---|---|---|---|
| 1xx | 100-199 | 情報応答 (Informational) | 100 Continue, 101 Switching Protocols, 103 Early Hints |
| 2xx | 200-299 | 成功 (Successful) | 200 OK, 201 Created, 204 No Content |
| 3xx | 300-399 | リダイレクト (Redirection) | 301 Moved Permanently, 304 Not Modified |
| 4xx | 400-499 | クライアントエラー (Client Error) | 400 Bad Request, 404 Not Found, 429 Too Many Requests |
| 5xx | 500-599 | サーバーエラー (Server Error) | 500 Internal Server Error, 503 Service Unavailable |
この分類の設計上の要点は、クライアントが未知のステータスコードを受け取っても、先頭桁だけで適切な挙動を取れることです。RFC 9110 §15.1 はこう述べています: 未認識の 4xx コードを受け取ったクライアントは 400 と同等に扱い、未認識の 5xx は 500 と同等に扱うべき、と。将来新しいコードが追加されても、古いクライアントが破綻しない仕組みです。
仕様の変遷 — RFC 2068 から RFC 9110 への 25 年
HTTP の仕様は 25 年間で 4 世代を経て磨かれてきました:
| RFC | 年月 | バージョン | 備考 |
|---|---|---|---|
| RFC 1945 | 1996-05 | HTTP/1.0 | ステータスコード初定義 (16 個) |
| RFC 2068 | 1997-01 | HTTP/1.1 | 初版。100 Continue 追加、持続的接続デフォルト化 |
| RFC 2616 | 1999-06 | HTTP/1.1 | 改訂版。10 年以上 Web の基盤として君臨 |
| RFC 7230-7235 | 2014-06 | HTTP/1.1 | 6 分冊に分割。曖昧さを解消、ABNF を厳密化 |
| RFC 9110-9112 | 2022-06 | HTTP | バージョン番号を外し「HTTP Semantics」として統一。HTTP/2 (RFC 9113)、HTTP/3 (RFC 9114) と共通の意味論 |
特に重要なのは 2022 年の改訂です。RFC 9110 は「HTTP/1.1 の仕様」ではなく「HTTP の意味論」として再定義されました。ステータスコードの定義は HTTP/1.1、HTTP/2、HTTP/3 のすべてで共通です。トランスポート層 (TCP, QUIC) が変わっても、ステータスコードの意味は変わりません。
418 I'm a teapot — エイプリルフールが公式になるまで
418 I'm a teapot は RFC 2324 (1998 年 4 月 1 日) で定義されました。この RFC は HTCPCP (Hyper Text Coffee Pot Control Protocol) というコーヒーポットを HTTP で制御するジョーク仕様で、エイプリルフール RFC の傑作として知られています。
ティーポットにコーヒーを淹れるよう要求すると 418 I'm a teapot が返される、という設定です。
問題はその後です。このジョークコードが Node.js の http モジュール、Google、Python の requests ライブラリなど、実際のソフトウェアに実装されてしまいました。RFC 9110 の著者 Roy Fielding は 418 を別の用途に再割り当てしようとしましたが、既に広く実装されていたため断念。
結局 RFC 9110 §15.5.19 では 418 を "(Unused)" とし、IANA レジストリで予約する形になりました。ジョークから始まったコードが、事実上永久欠番になったのです。
402 Payment Required — 25 年以上「将来のために予約」
402 Payment Required は HTTP/1.1 の初版 RFC 2068 (1997) から存在しますが、RFC 9110 §15.5.3 でも依然として「reserved for future use (将来の使用のために予約)」と記されています。25 年以上、一度も正式に使用方法が定義されたことがありません。
402 は「Web ペイメントのためのステータスコード」として構想されましたが、Web 上での決済手段が多様化しすぎ、HTTP レベルで統一的なペイメントプロトコルを定義することが現実的でなくなりました。
非公式には、API のレート制限超過やサブスクリプション切れを示すために 402 を返すサービス (Shopify, Stripe の一部エンドポイント) がありますが、標準的な用法とは言えません。インターネット考古学的には、Berners-Lee が構想した「マイクロペイメントで Web コンテンツに課金する」という 1990 年代の夢の残滓とも言えます。
103 Early Hints — パフォーマンス最適化の新顔
103 Early Hints は RFC 8297 (2017 年 12 月) で定義された比較的新しいステータスコードです。ステータスは Experimental (実験的) ですが、2023 年以降主要ブラウザがすべてサポートしています。
用途は明確で、サーバーが最終レスポンス (200 OK) を準備している間に、先行して Link ヘッダを送信し、ブラウザに CSS・フォント・JavaScript の先読み (preload) を開始させます:
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </app.js>; rel=preload; as=script
(... サーバーが DB 問い合わせ等を実行中 ...)
HTTP/1.1 200 OK
Content-Type: text/html
...
103 は「最終レスポンスの前に送る暫定レスポンス」という 1xx クラスの本来の役割を体現しています。Cloudflare や Fastly の CDN が対応しており、LCP (Largest Contentful Paint) の改善に有効です。
IANA レジストリ — ステータスコードの「戸籍」
HTTP ステータスコードの公式な一覧は IANA (Internet Assigned Numbers Authority) が管理する HTTP Status Code Registry にあります。
2026 年現在、登録済みのコードは約 63 個。100-599 の範囲には 500 個のスロットがあるため、まだ大部分が未割り当てです。新しいステータスコードの追加には IETF による標準化手続きが必要で、気軽には追加できません。
未割り当てコードの中には、コミュニティで非公式に使われているものもあります:
- 444 — nginx 独自。レスポンスを返さずに接続を閉じる
- 499 — nginx 独自。クライアントがレスポンスを待たずに接続を切断
- 529 — Qualys SSL Labs が使用 (非標準)
これらは IANA に登録されていない非公式コードであり、ソフトウェア固有の拡張です。RFC 9110 は未知のコードを先頭桁で処理するよう定めているため、こうした非公式コードも 4xx/5xx として適切に扱われます。
まとめ
- HTTP/0.9 (1991) にはステータスコードが存在しなかった — レスポンスは HTML 本文のみ
- RFC 1945 (1996) で 16 個のステータスコードが初定義、3 桁は FTP/SMTP の慣例を踏襲
- 5 クラス (1xx-5xx) の設計: 未知のコードも先頭桁で適切に処理できる前方互換性
- RFC 9110 (2022) で「HTTP Semantics」として再整理、HTTP/1.1/2/3 共通の意味論に
- 418 I'm a teapot: エイプリルフール RFC → 実装が広まり → 事実上の永久欠番
- 451: レイ・ブラッドベリ『華氏 451 度』へのオマージュ、法的制限の明示に使用
- 402 Payment Required: 25 年以上「将来のために予約」のまま未定義
- 103 Early Hints: リソースの先読みで LCP 改善、CDN が対応
- IANA レジストリが公式一覧、登録済み約 63 個 / 500 スロット
参考文献・ソース
- RFC 9110 — HTTP Semantics (June 2022, §15 Status Codes) ↗
- RFC 1945 — Hypertext Transfer Protocol -- HTTP/1.0 (May 1996) ↗
- RFC 2324 — Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0, April 1 1998) ↗
- RFC 7725 — An HTTP Status Code to Report Legal Obstacles (February 2016) ↗
- RFC 8297 — An HTTP Status Code for Indicating Hints (December 2017) ↗
- IANA — HTTP Status Code Registry ↗
記事作成に関する注記
本記事は AI(大規模言語モデル)を編集補助として活用して作成しています。 公開前に編集者が内容を確認していますが、事実誤認・仕様の解釈ミス・最新情報との齟齬が含まれる可能性があります。 重要な判断を行う際は、本文中の一次ソースや公式ドキュメントを必ずご自身でご確認ください。 誤りにお気づきの場合は、お問い合わせフォームよりご連絡いただけると助かります。


