DevToolBox

502・503・504 の違いと切り分け方

最終更新日: 2026-08-21公開日: 2026-07-26執筆: DevToolBox編集部

502 Bad Gateway503 Service Unavailable504 Gateway Timeout は いずれも「サーバー側で処理できなかった」ことを示す5xxエラーですが、意味と調べる場所は明確に異なります。 この違いを押さえると、障害対応の初動もAPI設計も迷いません。

502 = the upstream returned an invalid response. 503 = the service itself is temporarily unavailable. 504 = the upstream did not respond in time.

HTTP Status Codes

502・503・504を含む全ステータスコードの正式な定義をその場で検索。どのコードを返すべきかの判断に使えます。

今すぐ試す →

TL;DR

1. 比較表 / Comparison

観点502 Bad Gateway503 Service Unavailable504 Gateway Timeout
意味上流から不正な応答一時的に処理不能上流の応答が時間切れ
主な原因上流のクラッシュ・接続拒否・設定ミスアクセス集中・メンテナンス・ヘルスチェック全滅遅いSQL・外部API待ち・タイムアウト不整合
誰が返すかゲートウェイ(LB・プロキシ)サーバー本体またはLBゲートウェイ(LB・プロキシ)
訪問者の対処少し待って再読み込みRetry-Afterや案内に従って待つ待つ。フォーム再送信は履歴確認後
運営者が最初に見る場所上流の起動状態とエラーログ容量・ヘルスチェック・メンテ計画処理時間と各層のタイムアウト値
Retry-Afterの慣行通常付けない付けるのが推奨通常付けない

2. 判断フロー / Decision flow

図1: 502 / 503 / 504 の判断フロー
HTTP 502と503と504の判断フローチャート自身が過負荷やメンテナンスで処理不能なら503、上流に接続できない・不正応答なら502、期限内に応答が来ないなら504を返す判断手順自身が過負荷・メンテで処理不能か?上流に接続不能 or不正応答か?期限内に上流の応答が無いか?503502504YesYesYesNoNo

ポイントは「誰が異常を検出したか」です。503はサービス自身の宣言、 502と504は中継役が上流の異常を検出した結果で、その内訳が「不正応答なら502・時間切れなら504」です。

3. API・LB設計でどれを返すべきか / Which to return

Use 503 with Retry-After for planned maintenance and load shedding. Let the gateway emit 502 for invalid upstream responses and 504 for upstream timeouts — do not fake these from the app.

4. 監視・アラート運用での違い / Monitoring

コード初動で疑うこと確認するもの
502急増デプロイ直後のクラッシュ・接続設定の変更直近のデプロイ履歴、上流プロセスの生存、エラーログ
503急増容量不足・ヘルスチェック失敗RPS、オートスケール状況、正常ターゲット数
504急増遅い処理の混入・タイムアウト不整合レイテンシ分布(p95/p99)、遅いSQL、各層のタイムアウト値

3つを同じ「5xxエラー」として1本のアラートにまとめると、初動で見る場所が定まりません。 コード別にダッシュボードを分け、502はデプロイイベントと、503は容量メトリクスと、 504はレイテンシと並べて表示するのが定石です。

5. ログでの見え方 / Log examples

nginxのアクセスログでは、3つのコードは次のように現れます。upstream_response_time の値が切り分けの決め手になります。

# 502: 上流に接続できない(応答時間はほぼ0)
10.0.0.1 - [26/Jul/2026:12:00:01 +0900] "GET /api/users HTTP/1.1" 502 559 upstream_response_time=0.001

# 503: 自身が処理不能(メンテモードや過負荷)
10.0.0.1 - [26/Jul/2026:12:00:02 +0900] "GET /api/users HTTP/1.1" 503 197 upstream_response_time=-

# 504: タイムアウトまで待って諦めた(応答時間=タイムアウト値)
10.0.0.1 - [26/Jul/2026:12:00:03 +0900] "GET /api/report HTTP/1.1" 504 167 upstream_response_time=60.001

502は即座に失敗するため応答時間が極端に短く、504はタイムアウト設定値ちょうどまで待った形跡が残ります。 503で upstream_response_time が空なら、上流に到達する前に自身が返しています。

6. nginxで実際に再現する / Reproducing with nginx

nginxをリバースプロキシとして使い、上流(upstream)を止める・遅らせるだけで502と504を手元で再現できます。 以下は最小構成です。upstream ブロックで転送先を指定し、proxy_pass で中継します。

upstream backend {
    server 127.0.0.1:8080;
}

server {
    listen 8888;

    location / {
        proxy_pass http://backend;
        proxy_connect_timeout 3s;
        proxy_read_timeout 5s;
    }
}

この状態で上流(127.0.0.1:8080)のプロセスを止めてアクセスすると502が返り、 nginxの実装では error_log に次の形式の行が記録されます。

2026/08/21 12:00:01 [error] 1234#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 10.0.0.1, server: _, request: "GET /api/users HTTP/1.1", upstream: "http://127.0.0.1:8080/api/users", host: "example.com"

次に上流を起動したまま応答を proxy_read_timeout より遅くする(例えばアプリ側で10秒スリープさせる)と504が返り、 nginxの実装では次の形式の行が記録されます。

2026/08/21 12:00:10 [error] 1234#0: *2 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.0.0.1, server: _, request: "GET /api/report HTTP/1.1", upstream: "http://127.0.0.1:8080/api/report", host: "example.com"

エラーコード (111: Connection refused) は「接続自体を拒否された」ことを、(110: Connection timed out) は「接続または応答待ちが規定時間を超えた」ことを示すLinuxのerrno相当の番号で、 502と504の区別はこの番号とメッセージ文言(connect() failedupstream timed out か)で機械的に判定できます。

7. Cloudflare配下での見分け方 / Behind Cloudflare

Cloudflareのようなリバースプロキシ型CDNを経由している場合、502や504が「Cloudflare自身が生成したもの」か 「オリジンサーバーが生成し素通りしたもの」かを区別する必要があります。判断材料は次の通りです。

実務上は、Cloudflareのダッシュボード(Analytics & Logs)でエッジ側のステータスコード分布を確認し、 オリジンのアクセスログのコードと突き合わせるのが最も確実です。エッジのみで502が出てオリジンログに記録が無ければ、 Cloudflareからオリジンへの接続自体が失敗しています。

8. curlでの切り分けワンライナー / Diagnosing with curl

どの層がエラーを生成したかは、応答ヘッダとタイミングの両方から絞り込みます。まず詳細な通信ログとヘッダを確認します。

curl -sv https://example.com/api/users -o /dev/null

-v の出力に含まれる Server:Via: ヘッダを見ます。Server: cloudflareVia: にCDN・プロキシ名が入っていれば、そのレイヤーを経由したことが分かります。 オリジン側のWebサーバー名(Server: nginx 等)がそのまま見えている場合は、CDNがヘッダを書き換えずに素通りさせています。

次に、応答コードと所要時間を同時に取得し、タイムアウト起因かどうかを判定します。

curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://example.com/api/report

%{time_total} がゲートウェイやCDNのタイムアウト設定値(例えば30秒や60秒)にほぼ一致していれば504の典型パターンです。 逆に1秒未満で502が返る場合は、接続自体を即座に拒否されている(タイムアウトではなく接続不可)と判断できます。 502と503の切り分けには -w にヘッダ確認を組み合わせ、Retry-After の有無も見ます。

curl -s -o /dev/null -D - https://example.com/ | grep -i 'retry-after\|http/'

9. Retry-Afterの実挙動 / How Retry-After actually behaves

Retry-After ヘッダはRFC 9110で秒数指定とHTTP-date指定の2形式が認められています。

# 形式1: 秒数指定(相対時間)
Retry-After: 120

# 形式2: HTTP-date指定(絶対時刻、RFC 7231形式)
Retry-After: Fri, 21 Aug 2026 12:05:00 GMT

秒数指定は実装が単純でクロックのずれの影響を受けないため、多くのサーバー実装で採用されています。 HTTP-date指定は複数のプロキシ層を経由してヘッダが転送される間に時間が経過しても、絶対時刻なので誤差が生じにくい利点があります。

GooglebotはRetry-Afterを尊重してクロール頻度を調整することが案内されていますが、 指定した時間が経過すれば必ず即座に再クロールされるとは限らず、あくまでクロール優先度の調整材料の一つとして扱われます。 主要ブラウザはRetry-Afterを自動リロードには使わず、ページの表示情報として扱う(自動での再送信は行わない)のが一般的です。 API向けのHTTPクライアントライブラリでは、リトライ機構がRetry-Afterを自動的に読み取ってバックオフ時間に反映するものと、 無視して独自の指数バックオフのみを行うものが混在するため、外部APIを呼ぶ側は使用ライブラリの挙動をドキュメントで確認する必要があります。

10. 間違いやすいパターン / Common pitfalls

11. よくある質問 / FAQ

ブラウザに出たコードだけで原因は特定できる?

できません。同じ502でもLBが返したのかプロキシが返したのかで調査対象が変わります。運営者はレスポンスヘッダ(Server等)とログで「どの層が生成したか」を最初に特定します。

アプリから502や504を自分で返してもいい?

推奨しません。502と504は「中継役が観測した上流の異常」を表すコードなので、アプリ自身のエラーは500、過負荷なら503を返し、502/504はゲートウェイに任せると切り分けが単純になります。

3つとも出るサイトはどこが悪い?

過負荷が進行すると503(受付制限)→502(ワーカークラッシュ)→504(処理遅延)が同時多発します。この場合は個々のコードより容量とボトルネックの解消が先です。

Retry-Afterは秒数指定とHTTP-date指定のどちらを使うべき?

実装の単純さと誤差の少なさから秒数指定が広く使われていますが、どちらもRFC 9110で正式に認められた形式です。 受け取る側のクライアントが両形式に対応しているとは限らないため、自作のリトライ処理を書く場合は両方をパースできるようにしておくと安全です。

12. English summary

All three are gateway-related 5xx errors, but they point to different failures.502 Bad Gateway means the gateway received an invalid response or could not connect to the upstream — check whether the upstream process is alive.503 Service Unavailable means the service itself is temporarily unable to serve requests due to overload or maintenance — return it with a Retry-After header.504 Gateway Timeout means the upstream did not respond within the time limit — profile slow queries and align timeout values across CDN, load balancer, proxy, and application. In monitoring, alert on each code separately: 502 correlates with deployments, 503 with capacity, and 504 with latency.

よくある質問 / FAQ

502と504はどう違う?
どちらもゲートウェイが上流とやり取りできなかったエラーですが、502は「不正な応答を受けた・接続できない」、504は「制限時間内に応答が届かなかった」です。502は上流のクラッシュや設定ミス、504は遅い処理が典型原因です。
503と502はどちらがサイト側の問題?
どちらもサイト側の問題です。違いは応答の出どころで、503はサービス自身が「今は処理できない」と宣言する応答、502は中継役が上流の異常を検出して返す応答です。
メンテナンス時に返すべきコードは?
Retry-Afterヘッダ付きの503です。200でメンテナンス画面を返すと検索エンジンがその内容を本来のページとして扱う恐れがあり、502や504は障害と区別できなくなります。
5xxが混在する時はどこから調べる?
どの層がそのコードを生成したかの特定が先です。CDN・LB・リバースプロキシ・アプリのログを同じ時刻とリクエストIDで突き合わせ、最初に異常を検出した層を見つけます。過負荷時は上流の落ち方によって502と503が混在します。
What is the difference between 502, 503 and 504?
502 means the gateway received an invalid response from the upstream. 503 means the service itself is temporarily unable to handle requests, typically due to overload or maintenance. 504 means the upstream did not respond within the time limit.
モニタリングでは3つをどう使い分けて対応する?
502はデプロイ直後のクラッシュや接続設定を、503は容量とヘルスチェックを、504は遅い処理と各層のタイムアウト整合を最初に確認します。コード別にアラートを分けると初動が速くなります。
Retry-Afterは秒数指定とHTTP-date指定のどちらを使うべき?
実装の単純さと誤差の少なさから秒数指定が広く使われていますが、どちらもRFC 9110で正式に認められた形式です。受け取る側のクライアントが両形式に対応しているとは限らないため、自作のリトライ処理を書く場合は両方をパースできるようにしておくと安全です。

関連ツール / Related tools

関連ガイド / Related guides