目次
深夜に「サイトが502で開けません」という連絡が来て、とりあえずサーバーを再起動したら直った。しかし原因が分からないので、また起きるのではないかと不安なまま——こうした経験は多くの運用担当者にあるはずです。502・503・504は「サーバーの奥のどこかで詰まっている」ことしか教えてくれないため、当てずっぽうで対応しがちです。
この記事では、502・503・504それぞれの意味と、CDN・ロードバランサー・Nginx・アプリのどの層がそのエラーを返しているかを見分ける方法、典型的な原因(アプリ停止、ソケットの不一致、タイムアウト、ワーカー枯渇、DB接続待ち)、ログを見る順番、再現と暫定対処、恒久対策までを一本の手順として解説します。ログの場所やjournalctlの使い方はLinuxのログ管理入門で扱っているので、ここでは「何を、どの順に見るか」に集中します。
502・503・504の意味|「誰が」「何に困って」返しているか
3つのエラーは中継役の悲鳴
5xx系のうち502・503・504は、いずれも「リクエストを受け取った中継役(プロキシ)が、後ろにいる本来の処理役(アップストリーム)とうまくやり取りできなかった」ときに返されます。中継役とはNginx、ロードバランサー、CDNなどで、処理役とはアプリサーバー(Gunicorn、PHP-FPM、Node.js、Pumaなど)や、さらにその奥のバックエンドです。
| ステータス | 意味 | 中継役から見た状況 | 典型的な原因 |
|---|---|---|---|
| 502 Bad Gateway | アップストリームから不正な応答、または接続できなかった | 「つないだが相手がいない/変な返事が来た」 | アプリプロセス停止、ソケットパス・ポートの不一致、アプリのクラッシュ、応答ヘッダーが大きすぎる |
| 503 Service Unavailable | サービスが一時的に利用できない | 「受け付けられる状態ではない」 | メンテナンスモード、LBの正常なターゲットがゼロ、ワーカー・接続数の上限超過、レート制限 |
| 504 Gateway Timeout | アップストリームからの応答が時間内に来なかった | 「つないだが返事が遅すぎる」 | 重いクエリやN+1、DB接続待ち、外部APIの遅延、ワーカーが全部塞がっている |
覚え方として、502は「つながらない」、503は「受け付けない」、504は「返ってこない」です。この違いだけで、次に見るべき場所がかなり絞れます。
どの層が返しているかを見分ける
同じ502でも、CDNが返したのか、ロードバランサーが返したのか、Nginxが返したのかで原因の場所が変わります。見分ける手がかりは応答ヘッダーとボディです。
# ヘッダーだけを見る(-I)。Server・Via・cf-ray などから返している層を推定する
curl -sI https://example.com/ | head -20
# 例:Cloudflareが返している場合 → server: cloudflare, cf-ray: ... が付く
# 例:ALBが返している場合 → server: awselb/2.0
# 例:Nginxが返している場合 → server: nginx、ボディに <center>nginx</center>
# CDNやLBを迂回して直接オリジンに聞く(Hostヘッダーを付けてIP直打ち)
curl -sI -H "Host: example.com" http://10.0.11.21/ | head -5
「CDN経由だと502だがオリジン直打ちだと200」なら、原因はCDNとオリジンの間(証明書、Hostヘッダー、オリジン側のファイアウォール)にあります。「オリジン直打ちでも502」なら、Nginxより後ろの問題です。このように、手前の層を1枚ずつ剥がして、どこまで正常かを確認するのが切り分けの基本動作です。Webサーバーとアプリサーバーの役割分担が曖昧な方は、先にWebサーバーとアプリケーションサーバーの違いを読んでおくと以降が理解しやすくなります。
典型原因と特定方法|502編
アプリプロセスが動いていない
最も多いのがこれです。デプロイ直後の起動失敗、OOM Killerによる強制終了、依存ライブラリの欠落によるクラッシュなどで、Nginxの向き先にプロセスがいない状態です。
# プロセスの状態と直近のログ
systemctl status myapp
journalctl -u myapp -n 100 --no-pager
# Nginxのエラーログには「connect() failed (111: Connection refused)」が出る
tail -n 50 /var/log/nginx/error.log
# OOM Killerに殺されていないか
dmesg -T | grep -i -E "killed process|out of memory" | tail
「Connection refused」は「そのアドレス・ポートで誰も待ち受けていない」という意味なので、アプリの起動失敗か、次に述べる向き先の不一致が原因です。
ソケット・ポートの不一致と権限
Nginxはproxy_pass http://127.0.0.1:8000;に投げているのに、アプリは0.0.0.0:3000で待ち受けている。あるいはNginxはunix:/run/myapp.sockを見ているのに、アプリはソケットを/tmp/myapp.sockに作っている。Unixソケットの場合は、ソケットファイルの所有者・パーミッションが原因で「Permission denied (13)」になることもあります。
# 実際に待ち受けているアドレスとポートを確認
ss -ltnp | grep -E "8000|3000"
# Unixソケットの存在と権限
ls -l /run/myapp.sock
# Nginx側の向き先を確認
grep -rn "proxy_pass\|fastcgi_pass" /etc/nginx/
localhost・0.0.0.0・Unixソケットの違いによる「つながらない」は非常に多いので、localhost・0.0.0.0・127.0.0.1の違いもあわせて参照してください。
典型原因と特定方法|503・504編
503:ワーカー枯渇とヘルスチェック失敗
ロードバランサーが返す503の典型は「正常なターゲットがゼロ」です。アプリ自体は動いていても、ヘルスチェックのパスが404を返していたり、応答が遅くて閾値を超えたりすると、LBは全ターゲットを異常と判定し、振り分け先がなくなって503を返します。この場合、LBのターゲットグループの状態を最初に確認します。
Nginx自身が503を返すケースでは、limit_connやlimit_reqによる制限、PHP-FPMのプロセス上限(pm.max_children)到達、あるいはメンテナンス用の設定が残っている、といった原因が多く見られます。
# ALBのターゲットの健全性を確認(healthy がゼロなら503の原因)
aws elbv2 describe-target-health --target-group-arn arn:aws:elasticloadbalancing:...
# PHP-FPMがプロセス上限に達しているか(ログに "server reached pm.max_children" が出る)
grep "max_children" /var/log/php8.3-fpm.log | tail
# Nginxのレート制限で弾かれているか("limiting requests" / "limiting connections")
grep -E "limiting (requests|connections)" /var/log/nginx/error.log | tail
504:タイムアウトの連鎖
504は「アプリに届いたが処理が終わらない」状態です。原因の多くはアプリの外にあり、DBの重いクエリ、ロック待ち、コネクションプール枯渇、外部APIの応答遅延が代表例です。ここで見るべきは、Nginxのタイムアウト値と、アプリのワーカーが今何をしているかです。
# Nginxのタイムアウト設定(デフォルトは proxy_read_timeout 60s)
grep -rn "proxy_read_timeout\|proxy_connect_timeout" /etc/nginx/
# PostgreSQLで長時間実行中のクエリと待機状態を確認
psql -c "SELECT pid, now() - query_start AS running, state, wait_event_type, left(query, 80)
FROM pg_stat_activity
WHERE state <> 'idle' ORDER BY running DESC LIMIT 10;"
# アプリのワーカーが全部使用中か(Gunicornの例:プロセス数とCPU状態)
ps -o pid,stat,etime,cmd -C gunicorn
タイムアウトの値は「Nginx>アプリのワーカータイムアウト>DB・外部APIのタイムアウト」という順に、外側ほど長くなるように設計します。内側にタイムアウトがないと、1件の遅い外部APIがワーカーを何十秒も占有し、それが積み重なってワーカー全滅→504(あるいは503)へと連鎖します。この設計はタイムアウト・リトライ・サーキットブレーカーで詳しく扱っています。
ログを見る順番と切り分けの手順
外側から内側へ、時刻を揃えて
障害時に見るログの順番を決めておくと、慌てずに済みます。ポイントは、利用者がエラーを見た時刻を起点に、各層のログを同じ時刻で突き合わせることです。
- 監視・LB・CDNのダッシュボード:5xxの割合がいつから上がったか、全リクエストか一部か(特定のパスや端末だけか)。
- Nginxのerror.log:「upstream」を含む行を探す。
Connection refusedなら502(アプリ不在)、upstream timed outなら504、no live upstreamsなら全アップストリーム異常。 - アプリのログ/systemdジャーナル:クラッシュ、例外、起動失敗、ワーカータイムアウト(Gunicornなら「WORKER TIMEOUT」)。
- DB・外部依存:スロークエリログ、接続数、ロック待ち、外部APIのステータス。
- OSレベル:メモリ(OOM)、ディスクフル、ファイルディスクリプタ上限、CPU飽和。
# 障害時刻付近のNginxエラーを種類別に集計する(時刻は例)
grep "2026/09/02 03:1" /var/log/nginx/error.log \
| grep -oE "upstream (timed out|prematurely closed)|Connection refused|no live upstreams|Permission denied" \
| sort | uniq -c | sort -rn
トラブル事例:毎朝9時に数分間だけ504
症状:平日の9時前後に数分間だけ504が多発し、その後は自然に回復する。再起動しても関係なく、翌朝また起きる。
原因:Nginxのerror.logにupstream timed out (110: Connection timed out) while reading response headerが集中しており、同時刻のPostgreSQLのpg_stat_activityには、夜間バッチが作った巨大テーブルへの集計クエリが数十秒かかって残っていた。9時の出社直後のアクセス集中とこのクエリが重なり、コネクションプールが枯渇、以降のリクエストがすべて接続待ちになってワーカーが埋まり、Nginxの60秒でタイムアウトしていた。
暫定対処:問題の集計クエリにstatement_timeoutを設定して長時間実行を打ち切り、ワーカーが解放されるようにした。
恒久対策:集計に必要なインデックスを追加し、集計結果を夜間バッチ側で事前計算するよう変更。さらにPgBouncerを導入してアプリからの接続数を制御し、DB側の接続待ちを可視化した。プーリングの設計はデータベースのコネクションプーリング入門を参照してください。
再現・暫定対処・恒久対策の進め方
まず止血、次に原因、最後に再発防止
障害対応では「原因究明」と「復旧」を分けて考えます。利用者が困っている間は復旧が最優先ですが、再起動する前にログとプロセス状態を保全しておかないと、原因が永遠に分からなくなります。
- 保全:
ss -tnp、ps aux、free -m、df -hの出力と、直近のNginx・アプリ・DBのログをファイルに退避する(30秒で終わる)。 - 暫定対処:プロセス再起動、問題クエリの停止、ワーカー数やタイムアウトの一時的な緩和、問題のある機能のフラグオフなど、影響が小さい順に試す。
- 再現:ステージングで同じ負荷やデータ量を再現し、原因を確定する。再現できない仮説での「対策」は、たいてい別の問題を生む。
- 恒久対策:タイムアウトの階層設計、ヘルスチェックの見直し、リソース上限の適正化、監視アラートの追加(5xx率、ワーカー使用率、DB接続数)。
再発防止として特に効果が高いのは、「5xxの割合」と「アプリのワーカー使用率」と「DB接続数」の3つにアラートを設定することです。504が出てから気づくのではなく、ワーカーが8割埋まった時点で気づければ、多くの障害は未然に防げます。
まとめ
502は「つながらない」、503は「受け付けない」、504は「返ってこない」。この違いと、応答ヘッダーからどの層が返しているかを見分ける手順があれば、当てずっぽうの再起動から卒業できます。原因はアプリの停止、ソケット・ポートの不一致、ヘルスチェック失敗、ワーカー枯渇、タイムアウトの連鎖に集約され、外側から内側へ時刻を揃えてログを追えば、ほとんどは特定できます。そして再起動の前に状態を保全し、暫定対処の後に再現と恒久対策へ進むことが、同じ障害を二度と起こさないための道筋です。
まずは本番のNginxのerror.logで「upstream」を含む行を集計し、自社で起きている5xxの型を把握するところから始めてみてください。障害の根本原因の調査や、タイムアウト・監視設計の見直しに専門的な支援が必要な場合は、Harmonic Societyのシステム開発・インフラ支援にご相談ください。
Harmonic Society
この記事の内容、自社の業務でも活かせそうですか?
ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。
関連記事
Related / 9 articles
Notes & Insights
- プログラミング
DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用
DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。
- プログラミング
WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド
WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。
- プログラミング
セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説
CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。
- プログラミング
クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計
クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。
- プログラミング
秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除
APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。
- プログラミング
開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御
開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。
- プログラミング
ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方
NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。
- プログラミング
ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方
ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。
- プログラミング
localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決
localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。
Harmonic Society
「読んで終わり」にせず、自社の業務で試してみませんか?
AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。
無料・30分・オンラインOK|1営業日以内に返信します