- ネットワーク
- 技術 💻
HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき
HTTPステータスコードとは、サーバーがリクエストの結果を3桁の数字で返すもので、先頭の数字(1〜5)で「情報・成功・リダイレクト・クライアント側の問題・サーバー側の問題」の5種類に分かれます。 数字の意味がわかると、エラー画面を見た瞬間に「自分の操作を見直すのか、サーバー側の復旧を待つのか」を判断できます。
この記事では、IANAのHTTPステータスコード登録簿(2025-09-15更新版)とRFC 9110で確認した全コードを、意味・よくある原因・対処つきの1枚の表にまとめました。さらに、nginx 1.24とNode.js 22で代表的なコードを実際に返し、curl -iの出力をそのまま掲載しています。閲覧者向けと開発者向けの対処を分け、混同しやすいコードの比較表、CDNやロードバランサー独自のコード、Google検索への影響も公式情報で確認しています。
HTTPステータスコードの早見表(クラス別)
| クラス | 意味 | 読者がまず考えること | 代表例 |
|---|---|---|---|
| 1xx | 情報(処理の途中経過) | 通常は意識しなくてよい | 100, 101, 103 |
| 2xx | 成功 | 期待どおりか中身を確認 | 200, 201, 204 |
| 3xx | リダイレクト(別の場所へ) | 転送先と「恒久か一時か」を確認 | 301, 302, 304, 307, 308 |
| 4xx | クライアント側の問題 | URL・入力・認証・権限・回数を見直す | 400, 401, 403, 404, 429 |
| 5xx | サーバー側の問題 | サーバー・上流・設定を調べる/時間をおいて再試行 | 500, 502, 503, 504 |
よく出会うコードの「ひと言で」早見表です。
| コード | ひと言で | 閲覧者ができること | 開発者が最初に見る場所 |
|---|---|---|---|
| 200 | 成功 | ― | ― |
| 301 | 恒久的に移転 | ブックマークを更新 | リダイレクト設定 |
| 302 | 一時的に移転 | そのまま利用 | リダイレクト設定 |
| 304 | 変更なし(キャッシュを使う) | ― | ETag・Last-Modified |
| 400 | リクエストの形式が正しくない | Cookie削除・再読み込み | 送信データ・ヘッダー |
| 401 | 認証が必要 | ログインし直す | トークン・認証ヘッダー |
| 403 | 権限がない | 権限を持つ人に確認 | アクセス制御・ファイル権限 |
| 404 | 見つからない | URLを確認・サイト内検索 | ルーティング・ファイルの有無 |
| 405 | そのメソッドは使えない | ― | 許可メソッドの設定 |
| 413 | 送信データが大きすぎる | ファイルを小さくする | 上限設定(client_max_body_size等) |
| 429 | リクエストが多すぎる | 少し待つ | レート制限・Retry-After |
| 500 | サーバー内部のエラー | 時間をおく | アプリのログ |
| 502 | 上流から正しい応答がない | 時間をおく | 上流アプリの稼働・プロキシのエラーログ |
| 503 | 一時的に利用できない | 時間をおく | メンテナンス・過負荷・Retry-After |
| 504 | 上流の応答が時間切れ | 時間をおく | 上流の処理時間・タイムアウト設定 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき」
HTTPステータスコード全一覧(意味・原因・対処)
IANAの登録簿(最終更新2025-09-15)に登録されているコードをすべて掲載し、よく出会うものに★を付けました。名称はIANA/RFC 9110の表記です。「対処」は閲覧者・開発者の両方に役立つ最初の一手を書いています。
1xx 情報
| コード | 名称 | 意味 | よくある原因・場面 | 対処 |
|---|---|---|---|---|
| 100 | Continue | 本文を送ってよい | Expect: 100-continue付きの大きな送信 |
通常は不要 |
| 101 | Switching Protocols | プロトコルを切り替える | WebSocketへの切り替え | 不要(WebSocketが動かない場合はプロキシのUpgrade転送設定を確認) |
| 102 | Processing | 処理中(WebDAV) | 時間のかかるWebDAV操作 | 不要 |
| 103 | Early Hints | 先読みのヒント | LinkヘッダーでCSS等の先読みを指示 |
不要(表示速度の改善に使える) |
| 104 | Upload Resumption Supported | 再開可能アップロード対応(仮登録) | IETFで策定中の仕様 | 不要 |
2xx 成功
| コード | 名称 | 意味 | よくある原因・場面 | 対処 |
|---|---|---|---|---|
| ★200 | OK | 成功 | 通常の表示・取得 | 不要。ただしエラー画面を200で返していないか確認(ソフト404) |
| ★201 | Created | 作成された | POSTで新規登録。Locationに作成先 |
不要 |
| 202 | Accepted | 受け付けた(処理は後で) | 非同期ジョブの受付 | 状態確認用のURLを返す |
| 203 | Non-Authoritative Information | 中継者が内容を変更 | 変換プロキシ | 不要 |
| ★204 | No Content | 成功・本文なし | DELETEや保存APIの成功 | 本文を読もうとしない |
| 205 | Reset Content | 画面をリセットして | フォームの初期化 | 不要 |
| 206 | Partial Content | 一部だけ返した | 動画・大きなファイルのRange取得 |
不要 |
| 207 | Multi-Status | 複数の結果(WebDAV) | 一括操作の結果 | 本文の各結果を確認 |
| 208 | Already Reported | 報告済み(WebDAV) | バインディングの重複回避 | 不要 |
| 226 | IM Used | 差分を適用した | デルタエンコーディング | 不要 |
3xx リダイレクト
| コード | 名称 | 意味 | よくある原因・場面 | 対処 |
|---|---|---|---|---|
| 300 | Multiple Choices | 候補が複数 | 言語・形式の選択 | 候補から選ぶ |
| ★301 | Moved Permanently | 恒久的に移転 | URL変更、http→https、wwwの統一 | ブックマーク・内部リンクを新URLへ |
| ★302 | Found | 一時的に別の場所 | ログイン画面への誘導、キャンペーン | 恒久的な移転なら301/308へ |
| ★303 | See Other | 別URLをGETで見て | フォーム送信(POST)後の結果画面 | 不要(二重送信の防止に使える) |
| ★304 | Not Modified | 変更なし | If-None-Match/If-Modified-Sinceで再検証 |
不要(キャッシュが正しく効いている) |
| 305 | Use Proxy | (非推奨) | 現在は使われない | 使わない |
| 306 | (Unused) | 未使用 | ― | 使わない |
| ★307 | Temporary Redirect | 一時的に移転(メソッドを保つ) | POSTのまま一時転送、HSTSの内部転送 | 不要 |
| ★308 | Permanent Redirect | 恒久的に移転(メソッドを保つ) | APIのURL変更 | クライアントを新URLへ |
4xx クライアント側の問題
| コード | 名称 | 意味 | よくある原因 | 対処 |
|---|---|---|---|---|
| ★400 | Bad Request | リクエストの形式が不正 | 壊れたJSON、必須ヘッダーなし、大きすぎるCookie | 送信内容を確認。閲覧者はCookie削除 |
| ★401 | Unauthorized | 認証が必要 | ログイン切れ、トークンの期限切れ・未送信 | ログインし直す/Authorizationヘッダーを確認 |
| 402 | Payment Required | 将来のために予約 | 独自用途で使われることがある | サービスの説明を確認 |
| ★403 | Forbidden | 権限がない | 権限不足、IP制限、ファイルの読み取り権限 | 権限・アクセス制御を確認 |
| ★404 | Not Found | 見つからない | URLの誤り、削除、ルーティング漏れ | URL確認。移転なら301を設定 |
| ★405 | Method Not Allowed | メソッドが使えない | 静的ファイルへのPOST、未実装のPUT | Allowヘッダーで許可メソッドを返す |
| 406 | Not Acceptable | 求める形式で返せない | Acceptが厳しすぎる |
Acceptヘッダーを確認 |
| 407 | Proxy Authentication Required | プロキシの認証が必要 | 社内プロキシ | プロキシの認証情報を設定 |
| ★408 | Request Timeout | リクエストの送信が遅い | 通信が不安定、接続を開いたまま | 再送信 |
| ★409 | Conflict | 状態が競合 | 同時更新、重複登録 | 最新を取得してやり直す |
| ★410 | Gone | 恒久的に削除 | 意図的に終了したページ | 不要(削除を明示できる) |
| 411 | Length Required | 長さの指定が必要 | Content-Lengthがない |
ヘッダーを付ける |
| ★412 | Precondition Failed | 前提条件が不一致 | If-MatchのETagが古い |
最新を取得してやり直す |
| ★413 | Content Too Large | 本文が大きすぎる | 画像・ファイルのアップロード | ファイルを小さく/上限を見直す |
| ★414 | URI Too Long | URLが長すぎる | クエリ文字列に大量のデータ | POSTの本文で送る |
| ★415 | Unsupported Media Type | 形式に未対応 | Content-Typeの指定漏れ・誤り |
Content-Typeを正しく |
| 416 | Range Not Satisfiable | 範囲指定が不正 | ファイルサイズを超えるRange |
範囲を見直す |
| 417 | Expectation Failed | Expectに応えられない |
Expectヘッダー非対応 |
Expectを外す |
| 418 | (Unused) | 未使用(ジョーク由来の番号) | 独自実装 | 使わない |
| 421 | Misdirected Request | 宛先違い | HTTP/2の接続再利用と証明書の不一致 | サーバー名・証明書設定を確認 |
| ★422 | Unprocessable Content | 形式は正しいが内容が不正 | 入力チェックのエラー | エラー内容に沿って入力を直す |
| 423 | Locked | ロック中(WebDAV) | 他者が編集中 | 解除を待つ |
| 424 | Failed Dependency | 依存先の失敗(WebDAV) | 前の操作の失敗 | 前の操作を確認 |
| 425 | Too Early | 早すぎる | TLSの0-RTTデータの再送対策 | 通常の接続で再送 |
| 426 | Upgrade Required | プロトコルの変更が必要 | 新しいプロトコルが必須 | Upgradeヘッダーに従う |
| 428 | Precondition Required | 条件付きリクエストが必要 | If-Match必須のAPI |
ETagを付けて更新 |
| ★429 | Too Many Requests | リクエストが多すぎる | レート制限、連打、ボット | Retry-Afterの秒数待つ |
| 431 | Request Header Fields Too Large | ヘッダーが大きすぎる | Cookieの肥大化 | Cookie削除・ヘッダー削減 |
| 451 | Unavailable For Legal Reasons | 法的理由で提供できない | 法的な要請による制限 | 提供者の案内を確認 |
5xx サーバー側の問題
| コード | 名称 | 意味 | よくある原因 | 対処 |
|---|---|---|---|---|
| ★500 | Internal Server Error | サーバー内部のエラー | 例外、設定ミス、権限エラー | アプリ・サーバーのエラーログを確認 |
| ★501 | Not Implemented | 機能が未実装 | 未対応のメソッド | クライアント・サーバーの対応状況を確認 |
| ★502 | Bad Gateway | 上流から不正な応答 | 上流アプリが停止・異常終了、接続拒否 | 上流の稼働とプロキシのエラーログを確認 |
| ★503 | Service Unavailable | 一時的に利用不可 | メンテナンス、過負荷、上流が0台 | Retry-Afterを返す/待って再試行 |
| ★504 | Gateway Timeout | 上流が時間切れ | 重い処理、DBの遅延、タイムアウト設定 | 上流の処理時間とタイムアウト値を確認 |
| 505 | HTTP Version Not Supported | HTTPのバージョンに未対応 | 古い・新しいバージョン | 対応バージョンで送る |
| 506 | Variant Also Negotiates | 内容交渉の設定の循環 | サーバー設定 | 内容交渉の設定を確認 |
| 507 | Insufficient Storage | 保存領域不足(WebDAV) | ディスク容量 | 容量を確保 |
| 508 | Loop Detected | ループを検出(WebDAV) | 無限ループ | 構成を確認 |
| 510 | Not Extended | 拡張が必要(廃止扱い) | ― | 使わない |
| 511 | Network Authentication Required | ネットワークの認証が必要 | 公衆Wi-Fiのログイン画面 | ブラウザでログイン画面を開く |
IANAに未割り当ての番号(例:419、420、499、520など)は、製品やサービスが独自に使っているものです。後半の「CDN・ロードバランサー独自のコード」で整理します。
実際に返して確かめる(nginx+Node.jsのcurl -i実例)
nginx 1.24.0(Ubuntu)をリバースプロキシにし、上流にNode.js 22の小さなアプリを置いて、代表的なコードを実際に返しました。 以下はすべて実際の出力です(Dateは実行時刻、長いHTMLは一部省略)。
検証に使った設定(コピペ用)
# nginx.conf(抜粋)ポート7202で待ち受け、上流Nodeは7203
http {
limit_req_zone $binary_remote_addr zone=perip:1m rate=1r/s;
server {
listen 127.0.0.1:7202;
root /path/to/html;
client_max_body_size 1k; # 413の確認用に小さく
location = /old-page { return 301 /page.html; }
location = /campaign { return 302 /page.html; }
location = /api/v1/items { return 308 /api/items; }
location = /removed { return 410; }
location = /admin { deny all; } # 403
location = /limited { limit_req zone=perip nodelay; limit_req_status 429;
proxy_pass http://127.0.0.1:7203; }
location = /down { proxy_pass http://127.0.0.1:7204; } # 何も動いていないポート
location /api/ { proxy_pass http://127.0.0.1:7203; }
location = /slow { proxy_pass http://127.0.0.1:7203; proxy_read_timeout 1s; }
location = /maintenance { proxy_pass http://127.0.0.1:7203; }
}
}
// app.js(Node.js 22、外部ライブラリなし)
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/slow') { setTimeout(() => res.end('late\n'), 3000); return; }
if (req.url === '/api/items' && req.method === 'POST') {
let body = '';
req.on('data', c => body += c);
req.on('end', () => {
let data;
try { data = JSON.parse(body); } catch {
res.writeHead(400, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'invalid JSON' }) + '\n');
}
if (!data.name) {
res.writeHead(422, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'name is required' }) + '\n');
}
res.writeHead(201, { 'Content-Type': 'application/json', 'Location': '/api/items/42' });
res.end(JSON.stringify({ id: 42, name: data.name }) + '\n');
});
return;
}
if (req.url === '/api/me') {
res.writeHead(401, { 'WWW-Authenticate': 'Bearer realm="api"', 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'token required' }) + '\n');
}
if (req.url === '/maintenance') {
res.writeHead(503, { 'Retry-After': '120', 'Content-Type': 'text/plain' });
return res.end('maintenance\n');
}
if (req.url === '/api/crash') { throw new Error('boom'); } // 502の確認用
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok\n');
}).listen(7203, '127.0.0.1');
301・302・308:Locationヘッダーで転送先を返す
$ curl -i http://localhost:7202/old-page
HTTP/1.1 301 Moved Permanently
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html
Content-Length: 178
Location: http://localhost:7202/page.html
$ curl -i http://localhost:7202/campaign
HTTP/1.1 302 Moved Temporarily
Location: http://localhost:7202/page.html
$ curl -i -X POST http://localhost:7202/api/v1/items
HTTP/1.1 308 Permanent Redirect
Location: http://localhost:7202/api/items
nginxは302の理由句をMoved Temporarily(本文のタイトルは302 Found)と返しました。理由句(数字の後ろの英語)は実装によって異なり、意味を持つのは数字だけです。プログラムでは必ず数字で判定します。
304:キャッシュの再検証が成功した
$ curl -i http://localhost:7202/index.html
HTTP/1.1 200 OK
Content-Length: 15
Last-Modified: Tue, 29 Sep 2026 04:11:13 GMT
ETag: "6abb3a61-f"
<h1>hello</h1>
$ curl -i -H 'If-None-Match: "6abb3a61-f"' http://localhost:7202/index.html
HTTP/1.1 304 Not Modified
Last-Modified: Tue, 29 Sep 2026 04:11:13 GMT
ETag: "6abb3a61-f"
304は本文を返さず「手元のキャッシュを使ってよい」と伝える成功の合図です。エラーではありません。
400・422・201:APIの入力チェック
$ curl -i -X POST -H 'Content-Type: application/json' -d '{bad' http://localhost:7202/api/items
HTTP/1.1 400 Bad Request
Content-Type: application/json
{"error":"invalid JSON"}
$ curl -i -X POST -H 'Content-Type: application/json' -d '{}' http://localhost:7202/api/items
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{"error":"name is required"}
$ curl -i -X POST -H 'Content-Type: application/json' -d '{"name":"pen"}' http://localhost:7202/api/items
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/items/42
{"id":42,"name":"pen"}
Node.js 22は422の理由句を旧名のUnprocessable Entityで返しました(RFC 9110での名称はUnprocessable Content)。ここでも数字が同じなら意味は同じです。
HTTPのリクエスト自体が壊れているとき(例:HTTP/1.1でHostヘッダーがない)は、アプリに届く前にnginxが400を返します。
$ curl -i --http1.1 -H 'Host:' http://127.0.0.1:7202/
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 166
Connection: close
401・403・404・405・410
$ curl -i http://127.0.0.1:7202/api/me
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer realm="api"
{"error":"token required"}
$ curl -i http://localhost:7202/admin
HTTP/1.1 403 Forbidden
$ curl -i http://localhost:7202/nothing
HTTP/1.1 404 Not Found
$ curl -i -X POST http://localhost:7202/index.html
HTTP/1.1 405 Not Allowed
$ curl -i http://localhost:7202/removed
HTTP/1.1 410 Gone
401には「どう認証すればよいか」を示すWWW-Authenticateヘッダーを付けるのがRFC 9110の定めです。
413・429:大きすぎる・多すぎる
$ head -c 5000 /dev/zero | curl -i -X POST --data-binary @- http://localhost:7202/api/items
HTTP/1.1 413 Request Entity Too Large
Content-Type: text/html
Content-Length: 192
Connection: close
$ for i in 1 2 3; do curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:7202/limited; done
200
429
429
nginxのlimit_reqは既定で503を返すため、429にしたいときはlimit_req_status 429;を指定します。今回の検証では、/limitedをreturn 200で書いたときは制限がかからず、proxy_passに変えると429になりました。returnはlimit_reqより前の段階で応答を返すためです。
502・504・503:上流(アプリ)側の問題
$ curl -i http://localhost:7202/down
HTTP/1.1 502 Bad Gateway
nginxのerror.log:
connect() failed (111: Connection refused) while connecting to upstream,
upstream: "http://127.0.0.1:7204/down"
$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:7202/api/crash
502
nginxのerror.log:
upstream prematurely closed connection while reading response header from upstream
Node.jsのログ:
if (req.url === '/api/crash') { throw new Error('boom'); }
^
Error: boom
$ curl -i http://localhost:7202/slow
HTTP/1.1 504 Gateway Time-out
nginxのerror.log:
upstream timed out (110: Connection timed out) while reading response header from upstream
$ curl -i http://localhost:7202/maintenance
HTTP/1.1 503 Service Unavailable
Content-Type: text/plain
Retry-After: 120
maintenance
同じ「アプリの問題」でも、つながらない・途中で切れた=502、待ったが返ってこない=504と分かれます。例外で上流のプロセスが終了すると、その後のリクエストもすべて502(Connection refused)になりました。502・504はブラウザの画面ではなく、プロキシ(nginx)のerror.logを見ると原因の文が書かれています。
499:クライアントが先に切断した(nginx独自)
$ curl -s --max-time 0.5 http://127.0.0.1:7202/slow; echo "exit=$?"
exit=28
nginxのaccess.log:
127.0.0.1 - - [29/Sep/2026:13:11:36 +0900] "GET /slow HTTP/1.1" 499 0 "-" "curl/8.5.0"
499はクライアントに返されるコードではなく、nginxがログに記録する独自の値です。応答が遅くて利用者やクライアントが待ちきれなかったことを示すため、504と並んで「処理時間」の調査の手がかりになります。
混同しやすいコードの比較表
リダイレクト:301・302・303・307・308
| コード | 恒久/一時 | POSTを転送したとき | 主な用途 | 検索エンジン(Google) |
|---|---|---|---|---|
| 301 | 恒久 | GETに変わることがある | ページのURL変更、https化 | 転送先を正規URLとする強いシグナル |
| 302 | 一時 | GETに変わることがある | 一時的な誘導 | 弱いシグナル |
| 303 | 一時 | 必ずGETで取りに行く | フォーム送信後の結果画面 | 他のリダイレクトと同様に処理 |
| 307 | 一時 | メソッドと本文を保つ | APIの一時転送 | 弱いシグナル |
| 308 | 恒久 | メソッドと本文を保つ | APIのURL変更 | 強いシグナル |
ページの移転は301、APIのように「POSTのまま転送したい」なら307/308と覚えると迷いません。RFC 9110では301・308はキャッシュしてよい(ヒューリスティックにキャッシュ可能)とされています。一時的な転送に301を使うと、ブラウザが古い転送を覚え続けることがあるため、期間限定の転送は302/307にします。
401と403(要点)
| コード | 状況 | 次の一手 |
|---|---|---|
| 401 | 誰かわからない(未ログイン・トークン無効) | 認証し直せば通る可能性がある |
| 403 | 誰かはわかるが許可がない | 認証し直しても変わらない。権限の付与が必要 |
判断の起点は「ログインし直せば解決するか」です。
404と410
| コード | 意味 | 使う場面 | Google検索での扱い |
|---|---|---|---|
| 404 | 見つからない(理由は問わない) | URLの誤り、存在しないID | インデックスから削除、クロール頻度は徐々に低下 |
| 410 | 恒久的に削除した | 終了したページを明示したい | 4xxとして404と同様に扱われ、インデックスから削除 |
移転先があるなら404/410ではなく301にします。移転先のないページは、404と410のどちらでもGoogleのインデックスから削除されます。
400と422
| コード | 何がおかしいか | 例 |
|---|---|---|
| 400 | 形式(構文)が読めない | 壊れたJSON、必須ヘッダーなし |
| 422 | 形式は読めるが内容が条件を満たさない | 必須項目が空、値が範囲外 |
APIでは400に統一する方針もよく採られます。チームで方針をそろえ、本文にどの項目が問題かを返すことが大切です。
409と412
| コード | 状況 | 例 |
|---|---|---|
| 409 | 現在の状態と競合する | 同じ会員IDで重複登録、在庫の状態と矛盾 |
| 412 | 送られた前提条件(If-Match等)が一致しない |
編集中に他の人が先に更新し、ETagが変わっていた |
「条件付きリクエストのヘッダーで判定した」なら412、「業務上の状態が矛盾する」なら409です。
429と503
| コード | 誰の事情か | 返す場面 | 付けるとよいヘッダー |
|---|---|---|---|
| 429 | 特定のクライアントが多すぎる | レート制限 | Retry-After |
| 503 | サーバー全体の事情 | メンテナンス、過負荷 | Retry-After |
500・502・503・504
| コード | どこで問題が起きたか | 典型的なログ(nginx) | 調べる順番 |
|---|---|---|---|
| 500 | アプリ自身の中 | (アプリのログに例外) | アプリのエラーログ |
| 502 | 上流に接続できない/応答が壊れている | connect() failed (111: Connection refused)、upstream prematurely closed connection |
上流が起動しているか→ポート→異常終了の有無 |
| 503 | 意図的に止めている/受け付けられない | limit_reqの既定、上流0台 |
メンテナンス設定→負荷→上流の台数 |
| 504 | 上流の応答が時間内に来ない | upstream timed out (110: Connection timed out) |
遅い処理→DB→タイムアウト値 |
閲覧者向けの対処と開発者向けの対処
同じコードでも、画面を見ている人とサイトを運営する人ではできることが違います。
| コード | 閲覧者(ブラウザ利用者)ができること | 開発者・運用者がすること |
|---|---|---|
| 400 | 再読み込み、このサイトのCookieを削除 | リクエスト内容・ヘッダーサイズをログで確認 |
| 401 | ログインし直す | トークンの期限・送信方法、WWW-Authenticateを確認 |
| 403 | URLを確認、権限を持つ人に相談 | アクセス制御、IP制限、ファイルの読み取り権限を確認 |
| 404 | URLの打ち間違いを確認、トップやサイト内検索から探す | リンク切れを修正、移転したなら301 |
| 408 | 通信環境を確認して再送信 | タイムアウト値、クライアントの送信の遅さを確認 |
| 413 | ファイルを小さくして再送信 | client_max_body_size等の上限とアプリ側の上限をそろえる |
| 429 | 少し時間をおく | レート制限値、Retry-After、クライアントの再試行間隔を確認 |
| 431 | このサイトのCookieを削除 | Cookieの数と大きさを減らす |
| 500 | 時間をおいて再試行 | アプリの例外ログ、直前のデプロイを確認 |
| 502 | 時間をおいて再試行 | 上流の稼働、プロキシのerror.log |
| 503 | 時間をおいて再試行 | メンテナンス設定、負荷、Retry-After |
| 504 | 時間をおいて再試行、処理対象を小さくする | 遅いクエリ、タイムアウト値の整合(プロキシ<アプリになっていないか) |
| 511 | ブラウザでWi-Fiのログイン画面を開く | ― |
閲覧者の対処が「待つ」しかない5xxは、運用側がRetry-Afterやメンテナンス画面で見通しを示すと親切です。
CDN・ロードバランサー・Webサーバー独自のコード
IANAに登録されていないコードは、製品・サービスごとに意味が決まっています。 公式ドキュメントで確認したものをまとめます。
| コード | 製品 | 意味 | まず見るところ |
|---|---|---|---|
| 444 | nginx | 応答ヘッダーを送らずに接続を閉じる(return 444) |
意図した遮断設定か |
| 495 | nginx | クライアント証明書の検証エラー | 証明書・CA設定 |
| 496 | nginx | 必要なクライアント証明書が提示されない | クライアント側の証明書 |
| 497 | nginx | HTTPSのポートに通常のHTTPで送信 | URLのスキーム |
| 499 | nginx | クライアントが応答前に切断(ログに記録) | 処理時間、クライアントのタイムアウト |
| 520 | Cloudflare | オリジンが想定外の応答を返した | オリジンのログ、空応答や不正なヘッダー |
| 521 | Cloudflare | オリジンが応答しない(Webサーバー停止) | オリジンの稼働、ファイアウォール |
| 522 | Cloudflare | オリジンへの接続がタイムアウト | ネットワーク経路、ファイアウォール |
| 523 | Cloudflare | オリジンに到達できない | DNSのレコード、経路 |
| 524 | Cloudflare | 接続後、オリジンの応答が時間切れ | オリジンの処理時間 |
| 525 | Cloudflare | オリジンとのSSLハンドシェイクに失敗 | オリジンのTLS設定 |
| 526 | Cloudflare | オリジンのSSL証明書が無効 | 証明書の期限・ホスト名 |
| 530 | Cloudflare | 1xxx番台のエラーと一緒に返る | 表示される1xxxエラーの内容 |
| 460 | AWS ALB | クライアントがアイドルタイムアウト前に切断 | クライアントのタイムアウト値 |
| 463 | AWS ALB | X-Forwarded-ForのIPが多すぎる(上限30) |
多段プロキシの構成 |
| 464 | AWS ALB | リクエストとターゲットグループのプロトコルが不一致 | ターゲットグループの設定 |
| 561 | AWS ALB | リスナー認証でIdPがエラーを返した | IdPの設定 |
CDNやロードバランサーの5xxは「利用者 ⇔ CDN」と「CDN ⇔ オリジン」のどちらで起きたかを示しています。Cloudflareの52x台はオリジン側を調べると解決の近道です。
ステータスコードとSEO(Google検索への影響)
Google検索セントラルのドキュメント「HTTPステータスコード、ネットワークエラー、DNSエラーがGoogle検索に与える影響」の内容を要約します。
| コード | Googleの扱い |
|---|---|
| 2xx | インデックス登録の対象になる(保証はされない)。中身がエラー画面や空ページならSearch Consoleでソフト404と表示 |
| 301・308 | 転送先を処理すべきという強いシグナル |
| 302・307 | 転送先を処理すべきという弱いシグナル |
| 3xx全般 | 最大10回まで転送をたどる。転送元の本文は無視される |
| 4xx(429を除く) | インデックスに登録しない。登録済みのURLは削除。404はクロール頻度が徐々に下がる(410も4xxとして同様に扱われる) |
| 429・5xx | クローラーが一時的にクロールを遅くする。続くと登録済みURLもやがて削除。2xxに戻ると徐々に頻度を戻す |
SEOで押さえたいポイントは次の4つです。
- URLを変えたら301(または308)で新URLへ転送し、内部リンクも新URLに直す
- 存在しないページは404/410を返す(「見つかりません」画面を200で返すとソフト404になる)
- メンテナンスは503+
Retry-Afterで一時的な停止だと伝え、長引かせない - クロールを抑えたいときに401や403を使わない(Googleは429以外の4xxはクロール頻度に影響しないとしている)
ステータスコードの確認方法
| 方法 | 手順 | 向いている場面 |
|---|---|---|
| ブラウザの開発者ツール | F12 → ネットワークタブ → 対象の行の「ステータス」 | 画面操作と一緒に確認 |
| curl | curl -i URL(ヘッダーと本文)、curl -I URL(HEADで取得)、curl -s -o /dev/null -w "%{http_code}\n" URL(数字だけ) |
再現・自動化 |
| リダイレクトを追う | curl -sIL URL |
転送の連鎖の確認 |
| Search Console | ページのインデックス登録レポート | サイト全体の404・5xx・ソフト404 |
| サーバーログ | nginxならaccess.log(コード)とerror.log(理由) | 5xxの原因調査 |
よくある質問
Q. ステータスコードの後ろの英語(理由句)が記事と違います。
A. 理由句は実装ごとに異なり、意味を持つのは数字だけです。今回の実行でも、nginxは302をMoved Temporarily、Node.jsは422をUnprocessable Entityと返しました。HTTP/2では理由句そのものが送られません。
Q. 502と504はどちらがサーバーの問題ですか?
A. どちらもプロキシの先(上流)のサーバー側です。502は「接続できない・応答が壊れている」、504は「待ったが時間内に応答がない」です。nginxのerror.logにConnection refusedやupstream timed outなど理由が記録されます。
Q. 404と410はどちらを使えばよいですか? A. 通常は404で十分です。意図的に終了したページを明示したいときは410を使えます。Googleはどちらも4xxとしてインデックスから削除します。移転先があるなら301にします。
Q. 418 I'm a teapotは使えますか? A. IANAの登録簿では418は「(Unused)」として予約されています。ジョークとして知られていますが、実際のシステムでは意味の定まったコードを使うのが確実です。
まとめ
- 先頭の数字で分類:1xx情報、2xx成功、3xx転送、4xxクライアント側、5xxサーバー側
- 全コードはIANA登録簿とRFC 9110が基準。未登録の番号(499、52x、46xなど)は製品独自の意味
- 意味を持つのは数字だけ。理由句はnginxやNode.jsで表記が異なる
- 502は「つながらない・切れた」、504は「時間切れ」。原因はプロキシのerror.logに書かれる
- 転送は恒久なら301/308、一時なら302/307。POSTを保つなら307/308
- SEOでは301で転送、404/410で削除を明示、メンテナンスは503+Retry-After
- 閲覧者と開発者で対処を分けると、問い合わせや調査が速くなる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき」
株式会社RJCでは、Webサービスの開発や運用の現場で、ログやステータスコードから原因をたどる知識を仲間と共有しています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。