401 と 403
401Unauthorized— クライアントが未認証。資格情報が無い、または誤っている。「Unauthorized」という名称は誤解を招きやすく、実際は「未認証」を意味する。403Forbidden— クライアントは認証済みだが権限が無い。再認証しても解決しない。
すべての処理はブラウザ内で実行されます — ファイルや入力はサーバへ送信されません。
HTTP は最初の桁で応答コードを 5 クラスに分けます。区分は粗く、 「処理継続」から「フォントが見つからない」までを 1 クラスで まとめてしまいますが、最初の 1 桁だけで、リクエストが成功した のか、何が誤っているのか、原因がどちら側にあるのかが分かります。
| クラス | 範囲 | 名称 | 実際の意味 |
|---|---|---|---|
| 1xx | 100–199 | 情報 | 中間応答。リクエストを受理し、処理を継続中。最終応答は別途返される。 |
| 2xx | 200–299 | 成功 | リクエスト成功。意味はメソッドにより異なる。GET なら 200、リソース生成なら 201、「処理完了で本文なし」なら 204。 |
| 3xx | 300–399 | リダイレクト | クライアント側に追加の動作が必要。多くは別 URL への遷移、あるいはキャッシュが依然有効である旨の通知。 |
| 4xx | 400–499 | クライアントエラー | クライアント側の誤り。構文不正、認証欠落、存在しないリソースへの要求、受け入れ不能なデータ送信など。 |
| 5xx | 500–599 | サーバーエラー | サーバー側で正常なリクエストを処理しきれなかった。原因はサーバー側にあり、クライアントに非はない。 |
実運用の API バグの大半は、名前が似て見える数組のコードを取り違える ことで生じます。区別は意図的に設けられており、正しい選択がクライアント に次の動作を伝えます。
401Unauthorized— クライアントが未認証。資格情報が無い、または誤っている。「Unauthorized」という名称は誤解を招きやすく、実際は「未認証」を意味する。403Forbidden— クライアントは認証済みだが権限が無い。再認証しても解決しない。301Moved Permanently— リソースが恒久的に別 URL に移動。ブラウザはリダイレクト時にメソッドを GET に書き換えることがある (歴史的挙動)。302Found— 一時的リダイレクト。301 と同じメソッド書き換えの歴史的挙動を持つ。303 や 307 のつもりで誤って使われがち。307Temporary Redirect— 302 と似るがメソッドを保持しなければならない。POST はリダイレクト後も POST のまま。308Permanent Redirect— 301 と似るがメソッドを保持しなければならない。事実上の現代版 301。200OK— 本文付きの汎用成功。GET の既定。201Created— 新しいリソースが作成された。作成先を示す Location ヘッダーを添える。202Accepted— リクエストをキューに入れた。処理はまだ開始されておらず、非同期で完了する。204No Content— 成功だが本文を意図的に空にする。成功した DELETE の既定。400Bad Request— リクエスト自体が不正。JSON 構文エラー、必須ヘッダー欠落など、サーバーがパースできなかった場合。422Unprocessable Content— リクエストは理解できたが、データが意味的に不正な場合。例: メール欄に @ が無い、数量が負の値。502Bad Gateway— プロキシが上流サーバーから不正な応答を受け取った。プロキシが使えない応答を返してきた状態。503Service Unavailable— サーバー自身が一時的にダウン。過負荷やメンテナンスなど。Retry-After ヘッダーが添えられることが多い。504Gateway Timeout— プロキシが上流の応答を待ちすぎて諦めた。502 が「不正な応答」なのに対し、504 は「応答が無い」状態。REST API における慣習的な対応は短くまとまります。GET 成功: 200 (本文付き) または 304 (キャッシュが有効)。新規リソースを生成 する POST 成功: 201 と Location ヘッダー。PUT または PATCH 成功: 200 (更新後の本文付き) または 204 (本文なし)。DELETE 成功: 204。 バリデーション失敗: 422。認証不足: 401。権限不足: 403。リソース 未発見: 404。サーバー側のバグ: 500。
よくあるアンチパターンを 2 つ挙げておきます。1 つ目は、本文に エラーメッセージを入れて 200 を返す形 (status: 200, error: 'not found') です。監視ツールはすべてステータスコードを起点に 判定するため、この形式はすべてを無効化してしまいます。2 つ目は、 あらゆる失敗で 500 を返すことです。クライアント側に「再試行可能 (503)」「入力が誤り (400)」「サポート連絡が必要 (500)」を 区別する手段が無くなります。
現行の権威ある参照先は RFC 9110 (HTTP Semantics、 2022 年 6 月) で、過去の 12 本の RFC を 1 本に統合し、RFC 7231・ 7232 を明示的に廃止しています。日常的に使うコードの大半はすでに RFC 1945 (HTTP/1.0、1996 年) に含まれていました。308 Permanent Redirect は RFC 7538、421 Misdirected Request は RFC 7540、 451 Unavailable For Legal Reasons は RFC 7725 で追加されました。
実務的な参照には IANA の HTTP Status Code Registry が現行ソース となります。割り当て済みの全コードと定義 RFC を一覧化しています。 監査や規格適合報告で正式表現が必要なら RFC 9110 とレジストリを 引用してください。422 が何だったか思い出すだけなら、上の検索欄 のほうがずっと速いです。
検索ボックスにコード・名前・ユースケースのキーワード(`404`・`not found`・`redirect`・`unauthorized`・`idempotent` など)を入力すると、テーブルがリアルタイムでフィルタされます。クラスチップ(1xx / 2xx / 3xx / 4xx / 5xx)をクリックすればさらに絞り込めます。各行は正規名、1 行の説明、「いつ使うか」のヒント、それを定義する IETF セクションへのリンクを持ちます。中心は `RFC 9110`(長年使われた RFC 7231 / 7232 / 7233 / 7234 / 7235 シリーズを 2022 年に置き換えた改訂版)です。
API 設計、サーバログの読み込み、見慣れないコードが出るリクエストのデバッグなどに使ってください。注目されがちなのは 4xx / 5xx クラスですが、3xx のリダイレクトコードや 2xx の成功コードにも実際の意味的重みがあります。`301` と `308`、`200` と `204` と `201`、`409` と `422` はキャッシュやクライアントに異なる挙動を伝えます。適切なコードを選ぶことで、ライブラリ(axios・RestSharp・Spring)やインフラ(CloudFront・nginx・AWS API Gateway)が独自フックなしに予測可能な動きをします。
search: 422
422 Unprocessable Content (RFC 9110 §15.5.21) Use: request is syntactically valid but the server cannot process it for semantic reasons — failed validation, business rule violation. Often confused with 400.
`400 Bad Request` はリクエストそのものが壊れている(JSON が破損、必須ヘッダが欠落など)ことを示し、`422` はリクエストの意味が理解できるが内容が誤っている(email がすでに使用済み、age が 18 以上である必要があるなど)ことを示します。Stripe・GitHub・Twilio などの現代 API はバリデーションエラーに `422` を選ぶことが多く、バックエンドのログでも「クライアントがゴミを送った」と「クライアントが許されない操作を試みた」を分けやすくなります。
search: redirect permanent
301 Moved Permanently — historic permanent redirect; browsers may rewrite the method to GET on POST / PUT. 308 Permanent Redirect (RFC 7538) — same semantics but preserves the original method and body.
API のエンドポイントを新設するなら、リダイレクト後もクライアントが POST / PUT を続けるよう `308` を使います。SEO や旧 URL → 新 URL の移行で GET への書き換えが容認できる(かつ歴史的に期待される)場合は `301` を使います。同じ区別が一時リダイレクトにもあります — `302`(レガシー、GET に書き換える可能性あり)対 `307`(メソッド保持)。
search: unauthorized forbidden
401 Unauthorized — request lacks valid authentication. Server must return a WWW-Authenticate header. Despite the name, this is really "Unauthenticated". 403 Forbidden — request is authenticated but the principal is not allowed to perform this action. No WWW-Authenticate; retrying with different credentials won't help unless permissions change.
名前の付け方が紛らわしいのですが、`401` は認証(あなたは誰?)、`403` は認可(何をしてよいか?)についてです。よくあるパターンは、認証トークンが欠落・期限切れの場合は `401`(クライアントは再ログインすべき)、トークンは有効だがスコープが不足している場合は `403`(クライアントは権限昇格を要求すべき)を返すことです。API によっては、未認可の呼び出し元にリソースの存在を漏らさないために `403` の代わりに `404` を返すこともあります。
コードは IANA の HTTP ステータスコードレジストリから取得しています。これが公式な情報源です。現在の中核定義は RFC 9110(HTTP Semantics、2022 年 6 月)にあり、RFC 9111(Caching)や、7538(308 リダイレクト)・6585(precondition required・too many requests)・8297(early hints)などのトピック別 RFC が拡張を担います。各行はそれを定義するセクションへのリンクを持つため、仕様で裏取りできます。
レジストリは緩やかで、IETF プロセスを通せば誰でもコードの割り当てを申請できます。コモンなもの(`200`・`404`・`500`)もあれば、ニッチなもの(エイプリルフール RFC の `418 I'm a teapot`、『華氏 451 度』にちなんだ `451 Unavailable For Legal Reasons` など)もあります。狭いプロトコル向けのものもあり、WebDAV は RFC 4918 で 207 / 422 / 423 / 424 / 507 を追加しました。本リファレンスはすべて表示しているので、CDN のログやサードパーティ API に出てきたときも認識できます。
違法ではありませんが誤解を招きます。HTTP ステータスコードは *インフラ層*(ロードバランサ・リトライライブラリ・キャッシュ層・監視ダッシュボードなど)と対話するものです。論理的には失敗なのに `200` を返すと、CDN はそのエラーレスポンスをキャッシュし、リトライライブラリは呼び出しを成功とみなし、オンコールのダッシュボードは緑のドットでプロットしてしまいます。`2xx` は実際の成功にのみ使い、クライアントエラーには `4xx`、サーバエラーには `5xx` を使ってください。そうすれば周辺エコシステムが正しく扱います。主な例外は GraphQL で、その仕様はプロトコル層が HTTP に依存しないため、エラーをボディに含めて `200` で返します。
2 つは役立ちます。`100 Continue` は HTTP/1.1 クライアントが `Expect: 100-continue` を付けて、大きなボディを送る前にサーバに受け取り可否を尋ねるためのもので、多くのサーバは透過的に処理します。`103 Early Hints`(RFC 8297、2017 年)はサーバが実際の `200` 応答が用意される前に CSS / JS のプリロードヒントを送れるようにします — Cloudflare や Fastly が対応しています。残り(WebSocket アップグレード用の `101 Switching Protocols`、WebDAV 用の `102 Processing`)はプロトコル固有です。日常的な API 開発で 1xx を見ることはまれです。
いずれも上流 / ゲートウェイ系の失敗ですが、見ている角度が異なります。**`502 Bad Gateway`** はプロキシが上流から *壊れた* 応答(コネクションリセット、不正な HTTP)を受け取ったことを示します。**`503 Service Unavailable`** はサーバ自身がリクエストを処理できない状態(過負荷、メンテナンス、グレースフルシャットダウンなど)で、`Retry-After` ヘッダを添えるべきです。**`504 Gateway Timeout`** はプロキシが上流の応答を待ちきれずタイムアウトしたことを示します。nginx → アプリの構成なら、`502` は「アプリがクラッシュ」、`503` は「アプリが『満杯です』と返答」、`504` は「アプリの応答が遅すぎる」を意味します。適切なコードは、オンコールが再起動・スケールアウト・レイテンシ調査のどれを選ぶかの判断材料になります。
厳密には不可です。IANA レジストリが正本であり、プロキシ・ブラウザ・ミドルウェアは未登録コードをそのクラスの既定として扱う可能性があります(4xx は何でも 400 のように、5xx は何でも 500 のように)。実装上はフレームワークが容認することも多く、先頭桁さえ意味があれば動きます。プライベート API では `419 Authentication Timeout`(Laravel)や `420 Method Failure`(Twitter 旧 API)など未登録コードが使われた例があります。新しい公開 API では登録済みコードに揃え、詳細はレスポンスボディに入れてください。クライアントは未知のコードを一様に無視するため、追加情報の価値が小さくなります。
HTTP ステータスコードは、サーバが応答とともに返す 3 桁の整数です。先頭桁が **クラス** を示します。`1xx` 情報(まれ、プロトコル固有)、`2xx` 成功、`3xx` リダイレクション、`4xx` クライアントエラー、`5xx` サーバエラー。RFC 9110(2022 年 6 月)は、それまでの RFC 7231 / 7232 / 7233 / 7234 / 7235 に分散していた定義を 1 つの文書に統合した、現行の規範的リファレンスです。IANA の HTTP ステータスコードレジストリが、割り当て済みコードの正規一覧を保持しています。
隣接するコード間の意味の差は、人が想像する以上に重要です。`200` と `204` はどちらも「成功」ですが `204` はボディを持たず、クライアントはパースしてはいけません。`201` はリソース作成を確認し、応答には新リソースの表現か `Location` ヘッダが含まれます。`301` と `308` はどちらも「恒久的リダイレクト」ですが `308` は HTTP メソッドを保持し、`301` は歴史的に POST を GET に書き換えます。`409 Conflict` と `422 Unprocessable Content` はどちらも「書き込みを拒否した」ですが、`409` は状態の衝突(同時編集・重複キー)、`422` はバリデーション失敗(email 形式が不正など)向けです。適切なコードを選ぶことはシグナリングであり、衒学ではありません。キャッシュ・リトライライブラリ・観測性ツールはコードを見るだけでボディを読まずに反応します。
日々の API 設計を形作る隣接概念が 3 つあります。**冪等性** はメソッドを分類し(`GET`・`PUT`・`DELETE` は冪等、`POST` は非冪等)、安全なリトライ挙動を決めます。ステータスコード設計はこれと連動し、クライアントは `503` で再試行するかどうかを判断できます。**キャッシュ**(RFC 9111)はどの応答が保存されるかを決めます。`200`・`203`・`204`・`300`・`301`・`404`・`405`・`410`・`414`・`501` は既定でキャッシュ可能、その他は明示ヘッダが必要です。**コンテントネゴシエーション** は `Accept`・`Accept-Language` などのヘッダを使い、提示候補のどれも合わない場合に `406 Not Acceptable` を返します。ステータスコードはこれら 3 つの中心に位置するため、適切に選ぶことがスタック全体に効きます。
リクエストの初期部分を受領。残りを送信して続行してよい。
Upgrade ヘッダに従いプロトコルを切替(HTTP → WebSocket 等)。
WebDAV: 処理中、まだレスポンスなし。
最終レスポンスの準備中、先行取得用のヒントを返す。
リクエスト成功。意味はメソッドに依存。
新しいリソースを作成。POST の典型的な応答。
リクエストは受理されたが未処理(非同期処理)。
変換プロキシによってレスポンスが書き換えられた。
成功したが本体なし。DELETE や冪等な更新で使用。
クライアントに文書ビューのリセット(フォームクリア等)を指示。
Range ヘッダによる部分応答。再開可能 DL やストリーミングで使用。
WebDAV: 本体内に複数のステータスコード(XML)。
WebDAV: 既出メンバーの再列挙を省略。
デルタエンコーディング: instance-manipulation で応答。
複数の表現が存在。クライアントが選択。
恒久的に移動。ブックマーク・リンクを更新すべき。
一時的リダイレクト。実装によりメソッドが変わることあり。
別 URL を GET するよう指示。POST/Redirect/GET の典型。
キャッシュ応答が有効。本体なし。
302 と同じだがメソッドを維持。
301 と同じだがメソッドを維持。
構文不正・フレーミング不正等、サーバが理解できないリクエスト。
認証が必要、または失敗。WWW-Authenticate ヘッダ参照。
有料リソース予約。実運用ではあまり使わない。
認証済みだがアクセス権なし。
対象 URL にリソースなし。最も頻発するエラー。
このリソースで未対応のメソッド。Allow ヘッダ参照。
Accept-* に合致するレスポンスを返せない。
401 のプロキシ版。
リクエストが遅すぎてサーバが切断。
現状と競合(同時編集等)。
恒久的に削除済み。転送先なし。
Content-Length が必須。
If-Match / If-Unmodified-Since の条件不一致。
リクエスト本体がサーバ上限超過。
URL が長すぎる。
このエンドポイントが対応しない Content-Type。
指定 Range が範囲外(EOF 超過等)。
Expect ヘッダの要件を満たせない。
エイプリルフール(RFC 2324)。一部サイトが不可能リクエストに返す。
この authority に答えられないサーバに送られた。
構文は OK だが意味的に無効。フォーム検証で多用。
WebDAV: リソースがロック中。
WebDAV: 先行リクエストが失敗。
リプレイの可能性があり処理を拒否。
プロトコル変更が必要。
条件付きリクエストが必要。lost-update を防ぐ。
レート制限。Retry-After ヘッダ参照。
リクエストヘッダ合計が上限超過。
法的要請により利用不可。名称は華氏 451 度より。
サーバ側の汎用エラー。バグや未処理例外。
メソッド未実装。
プロキシが上流から不正な応答を受領。
過負荷 or メンテナンス中。後で再試行。
上流サーバが応答する前にタイムアウト。
リクエストの HTTP バージョン未対応。
コンテンツネゴシエーションのループ検出。
WebDAV: 保存容量不足。
WebDAV: 処理中に無限ループ検出。
リクエスト処理に追加拡張が必要。
ネットワーク認証必須(キャプティブポータル)。