てぶら

HTTPステータスコード一覧 — よく使うコードの意味と原因・対処法

公開日:

Webサイトを開いたときの「404 Not Found」や、APIを呼んだときの「500 Internal Server Error」など、HTTPステータスコードは開発や運用で毎日のように目にします。数字の意味を正しく理解しておくと、エラーの原因を素早く切り分けられ、APIを設計するときにも適切なコードを選べるようになります。この記事では、よく使うコードの意味と原因・対処法を、紛らわしいものの違いとあわせて整理します。

ステータスコードの基本: 5つのクラス

HTTPステータスコードは、サーバーがリクエストをどう処理したかを表す3桁の数字です。意味は現在、RFC 9110(HTTP Semantics)で定められています。先頭の1桁で大きく5つのクラスに分かれます。

  • 1xx(情報): リクエストを受け取り、処理を続けている
  • 2xx(成功): リクエストが正常に処理された
  • 3xx(リダイレクト): 別のURLを参照するなど、追加の操作が必要
  • 4xx(クライアントエラー): リクエストの内容に問題がある
  • 5xx(サーバーエラー): リクエストは妥当だが、サーバー側で処理できなかった

クライアントが知らないコードを受け取った場合は、そのクラスの「x00」として扱うことになっています。例えば未知の「499」を受け取ったら、400と同じクライアントエラーとして処理されます。「404 Not Found」の「Not Found」の部分は理由句(reason phrase)と呼ばれる説明文で、プログラムが判断に使うのは数字のほうです。HTTP/2以降では理由句そのものが送られません。

レスポンスのステータスコードは、curlの -i オプションやブラウザの開発者ツールの「ネットワーク」タブで確認できます。

bash
curl -i https://example.com/            # ヘッダーと本文を表示
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/  # コードだけ表示

2xx(成功)と304でよく使うコード

  • 200 OK: 成功。GETなら取得したリソース、POSTなら処理結果を返す
  • 201 Created: 新しいリソースを作成した。作成したリソースのURLをLocationヘッダーで返すのが一般的
  • 202 Accepted: 受け付けたが処理は完了していない。非同期のジョブ登録などで使う
  • 204 No Content: 成功したが返す本文がない。DELETEや更新処理で使う
  • 206 Partial Content: Rangeヘッダーによる部分的な取得に成功した。動画のシークや分割ダウンロードで使われる
  • 304 Not Modified: キャッシュしている内容から変わっていない

304は3xxに分類されますが、実際には「キャッシュをそのまま使ってよい」という意味で、エラーではありません。ブラウザが If-None-Match(ETagの値)や If-Modified-Since を付けて条件付きリクエストを送り、内容が変わっていなければサーバーは本文なしの304を返します。開発者ツールで304が並んでいるのは、キャッシュが正しく機能している証拠です。

APIの設計では、エラーが起きたのに200を返し、本文の中で { "error": ... } のように失敗を伝える実装を見かけることがあります。これではHTTPクライアントや監視ツール、キャッシュがエラーを区別できないため、失敗には適切な4xx・5xxを返すのが基本です。

301・302・303・307・308の違い

リダイレクトのコードは種類が多く、使い分けに迷いがちです。「恒久的か一時的か」と「リダイレクト先でもメソッドを維持するか」の2つの軸で整理するとわかりやすくなります。

  • 301 Moved Permanently: 恒久的な移転。歴史的な経緯から、POSTがGETに変わることを許している
  • 302 Found: 一時的な移転。301と同様にPOSTがGETに変わることがある
  • 303 See Other: 別のURLをGETで参照させる。フォーム送信後に結果ページへ移動させる(PRGパターン)ときに使う
  • 307 Temporary Redirect: 一時的な移転。メソッドと本文を変えずに再送する
  • 308 Permanent Redirect: 恒久的な移転。メソッドと本文を変えずに再送する

GETでアクセスされるWebページの移転(ドメインの変更、HTTPからHTTPSへの移行、URL構造の変更など)には、301を使うのが一般的です。検索エンジンも301や308を恒久的な移転として扱い、評価を新しいURLに引き継ぎます。メンテナンス中の一時的な誘導やログイン画面への転送など、元のURLに戻る予定がある場合は302や307を使います。

POSTやPUTを受け付けるAPIのエンドポイントを移転する場合は、メソッドが変わらないことが保証される307・308を選びましょう。301や302では、多くのクライアントがPOSTをGETに変えて再送するため、リクエストの本文が失われてしまいます。

nginx
# nginx: HTTP から HTTPS へ恒久的にリダイレクトする
server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

301はブラウザに長期間キャッシュされることがあり、設定を間違えると修正後も古いリダイレクトが残り続けます。動作を確認している段階では302で試し、問題がないことを確認してから301に切り替えると安全です。

4xx(クライアントエラー)の意味と対処

  • 400 Bad Request: リクエストの形式が不正。JSONの構文エラーや必須パラメーターの不足を確認する
  • 401 Unauthorized: 認証されていない。トークンの付け忘れや有効期限切れを確認する
  • 403 Forbidden: 認証はできているが権限がない。ユーザーのロールやファイルのパーミッションを確認する
  • 404 Not Found: リソースが見つからない。URLの綴りや、末尾のスラッシュの有無、ルーティングの設定を確認する
  • 405 Method Not Allowed: そのURLではそのメソッドが使えない。許可されているメソッドはAllowヘッダーで返される
  • 409 Conflict: リソースの現在の状態と競合している。同時編集や一意制約の重複など
  • 410 Gone: 恒久的に削除された。404と違い、二度と戻らないことを明示する
  • 413 Content Too Large: 本文が大きすぎる。アップロードサイズの上限(nginxの client_max_body_size など)を確認する
  • 415 Unsupported Media Type: Content-Typeに対応していない。JSONを送るなら application/json を付ける
  • 422 Unprocessable Content: 形式は正しいが内容が不正。入力値のバリデーションエラーによく使われる
  • 429 Too Many Requests: レート制限を超えた。Retry-Afterヘッダーがあれば、その時間だけ待ってから再試行する

特に混同されやすいのが401と403です。401は「あなたが誰かわからない」状態で、正しい認証情報を送り直せば成功する可能性があります。401を返すときは、どの方式で認証すべきかをWWW-Authenticateヘッダーで示すことになっています。一方の403は「誰かはわかっているが、その操作は許可されていない」状態で、同じ認証情報で何度やり直しても結果は変わりません。名前は「Unauthorized」ですが、401の実際の意味は「未認証」である点に注意してください。

なお、存在すること自体を知られたくないリソースに対しては、403の代わりに404を返すことも認められています。例えば、他人の非公開リポジトリのURLにアクセスすると404になるのはこのためです。

5xx(サーバーエラー)の意味と切り分け

  • 500 Internal Server Error: サーバー内部の予期しないエラー。アプリケーションの例外やバグが多く、まずサーバーのエラーログを確認する
  • 501 Not Implemented: サーバーがそのメソッドに対応していない
  • 502 Bad Gateway: プロキシやゲートウェイが、背後のサーバーから不正な応答を受け取った
  • 503 Service Unavailable: 過負荷やメンテナンスで一時的に使えない。Retry-Afterで再開の目安を伝えられる
  • 504 Gateway Timeout: プロキシやゲートウェイが、背後のサーバーからの応答を待ちきれずにタイムアウトした

nginxやロードバランサーの背後でアプリケーションを動かしている構成では、502と504の違いが原因の切り分けに役立ちます。502は、アプリケーションのプロセスが落ちている、ポート番号が間違っている、接続を拒否されたなど「まともな応答が返ってこなかった」ケースです。504は、アプリケーションは動いているものの、重いクエリや外部APIの待ちで処理に時間がかかり、プロキシのタイムアウト時間を超えたケースです。

502ならアプリケーションのプロセスの状態と接続先の設定を、504ならアプリケーションの処理時間とプロキシのタイムアウト設定(nginxの proxy_read_timeout など)を確認しましょう。計画的なメンテナンスでは、500ではなく503を返しておくと、検索エンジンやクライアントに「一時的な停止」であることが伝わります。

このサイトのHTTPステータスコード一覧では、1xxから5xxまでの主要なコードを、コード番号・英語の理由句・日本語の説明のいずれでも検索できます。見慣れないコードに出会ったときの確認に使ってください。