HTTP ステータスコード
すべての HTTP ステータスコードと、その意味や使いどころ。
このツールについて
HTTP ステータスコードを番号や名前で調べられます。それぞれにわかりやすい説明と返すべき場面のメモがあり、API の設計や失敗したリクエストの調査に役立ちます。
使い方
- 404 のようなステータスコード、または redirect や rate limit のような単語を入力します。
- クラスで絞り込み: 1xx 情報、2xx 成功、3xx リダイレクト、4xx クライアントエラー、5xx サーバーエラー。
- 各コードの意味と返すべき場面を確認します。
よくある質問
- 401 と 403 の違いは何ですか?
- 401 はクライアントが認証されていないこと(トークンがない、期限切れなど)を意味します。403 はクライアントは認証済みだが、その操作が許可されていないことを意味します。
- 検証エラーには 400 と 422 のどちらを返すべきですか?
- どちらも使われます。一般的な慣習では、解析できないリクエストには 400、形式は正しいが値の検証に失敗したリクエストには 422 を使います。
- 301 と 308 はどう使い分けるべきですか?
- どちらも恒久的なリダイレクトです。301 ではブラウザーが POST を GET に変えることがありますが、308 ではメソッドとボディが保持されることが保証されます。単なるページの移転なら 301 で問題ありません。
- 502 と 504 の違いは何ですか?
- どちらもプロキシやロードバランサーから返されます。502 は背後のサーバーが無効な応答を返したかクラッシュしたこと、504 は時間内に応答しなかったことを意味します。
- ステータスコード 0 とは?
- HTTP ステータスではありません。ブラウザーは、レスポンスがスクリプトに届かなかったときに 0 を報告します。リクエストが CORS でブロックされた、キャンセルされた、ネットワークエラーや DNS エラーが発生した、混在コンテンツとしてブロックされた、などの場合です。本当の理由は、ブラウザーのコンソールと「ネットワーク」タブで確認してください。
- 403 の代わりに 404 を返してもいいですか?
- はい。RFC 9110 では、リソースを見る権限がないかもしれない相手にその存在を明かしたくない場合、サーバーが 404 を返すことを認めています。GitHub はプライベートリポジトリでこうしています。クライアントがリソースの存在を知っていてもよいが、アクセスは許可されない場合は 403 を使ってください。
- デフォルトでキャッシュできるステータスコードは?
- RFC 9110 では、Cache-Control ヘッダーや Expires ヘッダーで別の指定がない場合、200、203、204、206、300、301、308、404、405、410、414、501 のレスポンスはヒューリスティックにキャッシュできます。そのため、CDN がしばらくの間 404 を返し続けることがあります。これを制御するには、明示的なキャッシュヘッダーを送ってください。
HTTP ステータスコードとは?
すべての HTTP レスポンスは、リクエストがどうなったかをクライアントに伝える 3 桁のステータスコードで始まります。コードとその意味は RFC 9110 で定義されており、RFC 6585 の 429 Too Many Requests のように、他の RFC で追加されたものもいくつかあります。最初の桁がクラスを決めます。1xx は情報、2xx は成功、3xx はリダイレクト、4xx はクライアントエラー、5xx はサーバーエラーです。知らないコードを受け取ったクライアントは、それを同じクラスの x00 のコードとして扱います。
ほとんどのソフトウェアが判断に使うのはクラスです。ブラウザーは 3xx のリダイレクトに従い、リトライ処理は通常、一部の 5xx レスポンスはリトライしますが、ほとんどの 4xx はリトライしません。監視では 5xx が自分の側のエラーとして数えられます。数字の後の「Not Found」のようなリーズンフレーズは情報提供のためだけのもので、HTTP/2 では完全に省かれます。そのため、一緒に送るメッセージよりも、正しい番号を選ぶことのほうが重要です。
API はどの HTTP ステータスコードを返すべき?
まずはよくあるケースから。ボディ付きで読み取りや更新が成功したら 200、POST で何かを作成したら Location ヘッダー付きで 201、DELETE の後など返すものがない場合は 204 を返します。処理がキューに入れられて後で完了する場合は 202 を使います。ボディにエラーメッセージを入れて 200 を返すのは避けてください。クライアント、キャッシュ、監視ツールはどれも、まずステータスコードを信頼します。
エラーでは、クライアントの責任と自分の責任を区別します。不正な形式の入力には 400、リソースが存在しない場合は 404、メールアドレスの重複のような競合には 409、レート制限には Retry-After ヘッダー付きで 429 を使います。5xx はサーバー側の障害のために取っておき、スタックトレースを返すのではなく詳細をログに記録してください。RFC 9457 の Problem Details のような一貫したエラーボディがあれば、クライアントは役に立つメッセージを表示できます。
リクエストのステータスコードを確認する方法
ブラウザーでは、開発者ツールを開いて「ネットワーク」タブに切り替え、ページを再読み込みします。「ステータス」列には、スクリプトによる失敗した fetch 呼び出しも含め、すべてのリクエストのコードが表示されます。コマンドラインでは、curl -i はボディの前にステータス行とレスポンスヘッダーを出力し、curl -I は HEAD リクエストを送ってヘッダーだけを表示します。-L を追加するとリダイレクトをたどるため、すべての中継先を確認できます。
予想外のコードが返ってきたら、誰がそれを送ったかを突き止めましょう。502、503、504 は、アプリではなく nginx、ロードバランサー、CDN から返されることが多いため、Server ヘッダーとプロキシのログを確認してください。存在するはずのルートで 404 が返る場合は、たいていベースパスの誤りか末尾のスラッシュの不一致です。一方、405 はパスは存在するもののそのメソッドには対応していないことを意味します。curl コマンドの作成・変換ツールを使えば、失敗したリクエストを再構築できます。
HTTP ステータスコード一覧
すべてのステータスコードの意味と返すべき場面を、クラス別にまとめました。
情報 (1xx)
| コード | 名前 | 意味 | 使う場面 |
|---|---|---|---|
| 100 | Continue | サーバーはリクエストヘッダーを受け取りました。クライアントはボディを送信してください。 | クライアントが Expect: 100-continue で問い合わせたときに自動的に送信されます。 |
| 101 | Switching Protocols | サーバーはクライアントが要求したプロトコルに切り替えます。 | 接続を WebSocket にアップグレードする場合。 |
| 103 | Early Hints | ブラウザーがプリロードを開始できるようにする事前のヘッダー。 | ページの生成中に、CSS やフォント用の Link ヘッダーを送る場合。 |
成功 (2xx)
| コード | 名前 | 意味 | 使う場面 |
|---|---|---|---|
| 200 | OK | リクエストは成功しました。 | 成功した GET、または結果を返す POST のデフォルト。 |
| 201 | Created | 新しいリソースが作成されました。 | 何かを作成する POST の後。作成したものを指す Location ヘッダーを含めます。 |
| 202 | Accepted | リクエストは受け付けられましたが、まだ処理されていません。 | キューに入った処理やバックグラウンドジョブ。進行状況を確認する方法を返します。 |
| 204 | No Content | 成功したが、返す内容はない。 | ボディを返さない DELETE や PUT。 |
| 206 | Partial Content | リソースの一部だけが返されます。 | Range リクエストへの応答。動画のストリーミングや再開可能なダウンロードで使われます。 |
リダイレクト (3xx)
| コード | 名前 | 意味 | 使う場面 |
|---|---|---|---|
| 301 | Moved Permanently | リソースには新しい恒久的な URL があります。 | サイト再構成後の古い URL。ブラウザーや検索エンジンが記憶します。 |
| 302 | Found | リソースは一時的に別の URL にあります。 | 一時的なリダイレクト。クライアントが POST を GET に変えることがあるため、明示するには 303 か 307 を使うのがおすすめです。 |
| 303 | See Other | 結果を別の URL から GET で取得させる場合。 | フォームの POST 後のリダイレクト。再読み込みで再送信されないようにします。 |
| 304 | Not Modified | キャッシュされたコピーはまだ有効です。 | If-None-Match や If-Modified-Since 付きの条件付きリクエストへの応答。 |
| 307 | Temporary Redirect | 別の URL で同じリクエストを繰り返させる場合。 | メソッドとボディを維持しなければならない一時的なリダイレクト。 |
| 308 | Permanent Redirect | 新しい恒久的な URL で同じリクエストを繰り返させる場合。 | 301 と同様ですが、メソッドとボディを変更してはなりません。 |
クライアントエラー (4xx)
| コード | 名前 | 意味 | 使う場面 |
|---|---|---|---|
| 400 | Bad Request | リクエストの形式が不正か、無効です。 | 解析できない JSON、必須フィールドの欠落、型の誤り。 |
| 401 | Unauthorized | 認証情報がないか、無効です。 | トークンがないか、期限切れです。名前とは異なり、「未認証」を意味します。 |
| 402 | Payment Required | 予約済み。一部の API では支払いの問題に使われます。 | プランの上限に達したか、支払いに失敗しました。 |
| 403 | Forbidden | クライアントは識別されていますが、この操作は許可されていません。 | ログイン済みだが権限がない。 |
| 404 | Not Found | この URL には何も存在しません。 | 不明なルートや ID。クライアントが知るべきでないリソースを隠すためにも使われます。 |
| 405 | Method Not Allowed | この URL はその HTTP メソッドに対応していません。 | 読み取り専用エンドポイントへの POST。Allow ヘッダーを含めます。 |
| 406 | Not Acceptable | Accept ヘッダーに一致する表現がありません。 | クライアントが JSON 専用の API に XML を要求しました。 |
| 408 | Request Timeout | クライアントがリクエストの送信に時間をかけすぎました。 | アイドル状態の接続。クライアントは安全に再試行できます。 |
| 409 | Conflict | リクエストが現在の状態と競合しています。 | 一意であるべき値の重複、または古いバージョンに基づく編集。 |
| 410 | Gone | リソースは存在していましたが、完全に削除されました。 | 削除されたコンテンツや廃止された API バージョン。404 より強い意味を持ちます。 |
| 411 | Length Required | Content-Length ヘッダーが必要です。 | サイズが宣言されていないアップロード。 |
| 412 | Precondition Failed | 条件付きヘッダーが一致しませんでした。 | 古い ETag を指定した If-Match。更新の消失を防ぎます。 |
| 413 | Content Too Large | リクエストボディがサーバーの受け付けるサイズを超えています。 | サイズ上限を超えるアップロード。 |
| 414 | URI Too Long | URL がサーバーで扱える長さを超えています。 | 巨大なクエリ文字列。データを POST のボディに移してください。 |
| 415 | Unsupported Media Type | ボディの形式がサポートされていません。 | JSON エンドポイントへのフォームデータの送信、または誤った Content-Type。 |
| 416 | Range Not Satisfiable | 要求されたバイト範囲がファイルの範囲外です。 | リソースの末尾を超えた Range リクエスト。 |
| 418 | I’m a teapot | 1998 年のエイプリルフールのジョークが定着したもの。 | イースターエッグ専用。 |
| 422 | Unprocessable Content | リクエストの形式は正しいものの、検証に失敗しました。 | 終了日が開始日より前など、値が無効な有効 JSON。 |
| 423 | Locked | リソースはロックされています。 | WebDAV、または他の人が編集中のレコード。 |
| 425 | Too Early | サーバーは、リプレイされる可能性のあるリクエストを処理するリスクを冒しません。 | TLS の早期データ(0-RTT)。 |
| 426 | Upgrade Required | クライアントは別のプロトコルに切り替える必要があります。 | より新しい TLS や HTTP バージョンを強制する場合。 |
| 428 | Precondition Required | リクエストは条件付きである必要があります。 | 更新時に If-Match を必須にして、書き込みの消失を防ぐ場合。 |
| 429 | Too Many Requests | クライアントのリクエストが速すぎます。 | レート制限。Retry-After ヘッダーを含めます。 |
| 431 | Request Header Fields Too Large | ヘッダーが大きすぎます。 | 大きすぎる Cookie がよくある原因です。 |
| 451 | Unavailable For Legal Reasons | 法的な理由によりブロックされています。 | 裁判所の命令により削除されたか、国によってブロックされたコンテンツ。 |
サーバーエラー (5xx)
| コード | 名前 | 意味 | 使う場面 |
|---|---|---|---|
| 500 | Internal Server Error | サーバーで問題が発生しました。 | 未処理の例外。詳細はログに記録し、クライアントには漏らさないようにします。 |
| 501 | Not Implemented | サーバーはこの機能をサポートしていません。 | サーバーがまったく認識できない HTTP メソッド。 |
| 502 | Bad Gateway | プロキシが背後のサーバーから無効な応答を受け取りました。 | nginx やロードバランサーの背後のアプリがクラッシュしたか、不正な応答を返しました。 |
| 503 | Service Unavailable | サーバーは現在リクエストを処理できません。 | メンテナンスまたは過負荷。復旧時期がわかっている場合は Retry-After を含めます。 |
| 504 | Gateway Timeout | プロキシが時間内に応答を受け取れませんでした。 | 上流のアプリが遅すぎるか、応答しません。 |
| 505 | HTTP Version Not Supported | この HTTP バージョンはサポートされていません。 | まれ。非常に古いか非常に新しいプロトコルバージョン。 |
| 507 | Insufficient Storage | サーバーに結果を保存する空き容量がありません。 | ディスクがいっぱいか、ストレージの割り当て上限に達しました。 |
| 508 | Loop Detected | サーバーが処理中に無限ループを検出しました。 | WebDAV、またはリダイレクトやプロキシのループ。 |
| 511 | Network Authentication Required | ネットワークにアクセスするにはクライアントのログインが必要です。 | ホテルや空港の Wi-Fi のキャプティブポータル。 |
うまく動かない、または結果がおかしいですか? このツールの問題を報告