502 Bad Gateway とは?原因と解決方法

Advertisement
502 Bad Gateway エラーとは?
502 Bad Gateway は、あなたに応答しているサーバーがゲートウェイまたはプロキシとして動作しており、その背後のサーバーから不正な応答を受け取ったことを意味する HTTP ステータスコードです。HTTP の標準仕様(RFC 9110 の 15.6.3 節)もまさにそう定義しており、サーバーが「ゲートウェイまたはプロキシとして動作中に、リクエストを処理するためにアクセスしたインバウンドサーバーから不正な応答を受け取った」状態を指します。
現代のウェブサイトの多くは、少なくとも2つの層で構成されています。nginx、Apache、Cloudflare、クラウドのロードバランサーといったフロントサーバーがあなたの接続を受け付け、そのリクエストを PHP-FPM、Node.js アプリ、Python の Gunicorn、コンテナなどのアップストリームのアプリケーションに渡します。そのアップストリームが停止している、クラッシュした、あるいはプロキシが扱えない内容を返した場合、プロキシはあなたに渡せるものがないため 502 を返します。
重要なのは、ゲートウェイ自体は正常に動作しているという点です。ゲートウェイはリクエストを受け取り、応答を返しました。問題はその一段奥にあります。
502 エラーのさまざまな表示
ステータスコードはどこでも同じですが、表示されるページはどのプロキシが生成したかによって異なります:
| 発生元 | ページの表示内容 |
|---|---|
| nginx | 502 Bad Gateway(その下に nginx と表示され、バージョンが併記されることもある) |
| Apache(mod_proxy) | Proxy Error. The proxy server received an invalid response from an upstream server. |
| Cloudflare | Error 502 Bad gateway(Browser / Cloudflare / Host のステータスボックス付き) |
| Microsoft IIS(ARR / ASP.NET Core) | HTTP Error 502.3 - Bad Gateway、または HTTP Error 502.5 - Process Failure |
| Google のサービス | 502. That's an error. The server encountered a temporary error… |
| ブラウザ / アプリ | HTTP Error 502、502 Proxy Error、Bad Gateway: The proxy server received an invalid response |
どの表示であっても、フッターに書かれたプロキシの名前は有用な手がかりです。サイト管理者に、どの層を調べるべきかを教えてくれます。
Advertisement
502・500・503・504 の違いとは?
5xx 系のコードはどれも「サーバーの問題」を意味しますが、それぞれ異なる層を示しています:
| コード | 名称 | 意味 | 典型的な原因 |
|---|---|---|---|
| 500 | Internal Server Error | リクエスト処理中にアプリケーション自体が失敗した | コードのバグ、PHP の致命的エラー、設定の誤り |
| 502 | Bad Gateway | プロキシがアップストリームから不正な応答を受け取った、または使える応答がなかった | アプリの停止・クラッシュ、ポートやソケットの誤り、大きすぎるヘッダー |
| 503 | Service Unavailable | サーバーが一時的にリクエストを拒否している | 過負荷、メンテナンスモード、レート制限 |
| 504 | Gateway Timeout | プロキシがアップストリームの応答を待ったが諦めた | 遅いデータベースクエリ、長時間実行されるスクリプト、短すぎるタイムアウト設定 |
簡単な覚え方:502 = アップストリームが不正な応答を返した(または接続を切った)、504 = アップストリームが時間内に応答しなかった。関連するエラーは次のガイドで詳しく解説しています:500 Internal Server Error、503 Service Unavailable、504 Gateway Timeout。
502 Bad Gateway の原因
アップストリームのアプリが動いていない。 PHP-FPM、Node、Gunicorn、またはコンテナがクラッシュした、デプロイ後に起動に失敗した、あるいは再起動中です。
プロキシの転送先が間違っている。
proxy_passやfastcgi_passが、誤ったポート、アップグレード前の古い PHP ソケットパス、あるいは Docker コンテナ内のlocalhostを指しています。一部のリクエストでアプリがクラッシュする。 特定のページがメモリ不足によるプロセスの強制終了や未処理の例外を引き起こし、応答する前に接続が閉じられます。
すべてのワーカーが使用中。 PHP-FPM が
pm.max_childrenに達し、新しいリクエストの行き場がありません。レスポンスヘッダーが大きすぎる。 大きな Cookie やサイズの大きいセキュリティヘッダーが、nginx の
proxy_buffer_sizeからあふれています。ロードバランサー配下での keep-alive の不一致。 アプリがアイドル接続をロードバランサーの想定より早く閉じるため、ロードバランサーが閉じかけの接続にリクエストを送ってしまいます。
プロキシとオリジンの間のファイアウォールやネットワークの変更。 たとえば、IP アドレスやファイアウォールルールが変わったオリジンに、CDN が到達できなくなった場合です。
Advertisement
訪問者として 502 エラーを解決する方法
他人のサーバーを修理することはできませんが、次の手順で問題が本当に相手側にあることを確認し、まれなローカル要因を取り除けます:
30〜60秒待ってから再読み込みする(Ctrl + R、Mac は Cmd + R)。多くの 502 は、デプロイや再起動が続く間だけのものです。
全員にとってダウンしているか確認する。 DNS Robot の HTTP ヘッダーチェッカー は当社のサーバーからページをリクエストし、正確なステータスコードを表示します。こちらでも 502 が返るなら、原因はあなたではなくサイトです。Ping テスト では、サーバーのマシンがそもそも応答するかを確認できます。
強制再読み込みとキャッシュ削除を行う。 Ctrl + Shift + R(Mac は Cmd + Shift + R)でキャッシュされたコピーを回避できます。古いエラーページが表示され続けている場合に有効です。
DNS をフラッシュする。 サイトが最近ホストを移転した場合に、新しいサーバーへ到達できるようにします。各システムでの手順は DNS をフラッシュする方法 をご覧ください。
VPN やプロキシをオフにする。 特に職場のネットワークでは、あなた自身のプロキシが失敗している「ゲートウェイ」である可能性があります。
別のブラウザや、モバイルデータ通信のスマートフォンで試す。 そこで表示されるなら、そのサイトの Cookie を削除してください。
自分のサーバーで 502 Bad Gateway を解決する方法
サーバー側から見ると、502 は比較的直しやすいエラーです。プロキシがほぼ必ず、何が問題だったかを正確にログへ記録しているからです。次の4つのチェックを順に進めてください。
Advertisement
1. プロキシのエラーログを読む
502 を再現してから、プロキシサーバーのエラーログの末尾を読みます:
| ログメッセージ | 意味 |
|---|---|
| connect() failed (111: Connection refused) while connecting to upstream | アップストリームのポートで何も待ち受けていない:アプリが停止しているか、別のポートで動いている |
| connect() to unix:/run/php/php8.x-fpm.sock failed (2: No such file or directory) | PHP-FPM のソケットが存在しない。通常は PHP のバージョン変更が原因 |
| connect() to unix:… failed (13: Permission denied) | nginx がソケットにアクセスできない:listen.owner / listen.group を修正する |
| upstream prematurely closed connection while reading response header | アプリがリクエスト処理中にクラッシュしたか、接続を閉じた |
| upstream sent too big header while reading response header from upstream | レスポンスヘッダーが proxy_buffer_size より大きい |
| no live upstreams while connecting to upstream | upstream ブロック内のすべてのサーバーが障害ありとマークされている |
# nginx
sudo tail -n 50 /var/log/nginx/error.log
# Apache
sudo tail -n 50 /var/log/apache2/error.log # Debian/Ubuntu
sudo tail -n 50 /var/log/httpd/error_log # RHEL/Alma/Rocky502 の大部分は次の nginx メッセージのどれかに当てはまり、それぞれが解決策を示しています:
2. アップストリームのアプリが動いているか確認する
# PHP-FPM(バージョンは環境に合わせて変更)
sudo systemctl status php8.3-fpm
sudo journalctl -u php8.3-fpm -n 50
# PM2 で動かしている Node.js
pm2 status
pm2 logs --lines 50
# Docker
docker ps -a # 再起動を繰り返しているコンテナを探す
docker logs --tail 50 <container>
# メモリの使いすぎで強制終了されていないか?
dmesg -T | grep -i "killed process"サービスが停止していたら起動し、停止した理由を突き止めます。失敗したデプロイ、新しいリリースの構文エラー、あるいは OOM キラー(メモリ不足によるプロセスの強制終了)などです。PHP-FPM のログに server reached pm.max_children setting とあれば、すべてのワーカーが使用中だったことを意味します。pm.max_children を上げるのはサーバーに十分な RAM がある場合だけにし、そうでなければワーカーを占有している遅いリクエストを探してください。
3. proxy_pass が正しいポートやソケットを指しているか確認する
nginx に指定された接続先と、実際に待ち受けているものを比較します:
# nginx はどこへプロキシしているか?
grep -rn "proxy_pass\|fastcgi_pass" /etc/nginx/sites-enabled/
# 実際に待ち受けているのは何か?
sudo ss -tlnp # TCP ポートとそのプロセス
ls -l /run/php/ # PHP-FPM のソケットファイルよくある不一致は2つあります。1つは、PHP をアップグレードした後、ソケットが php8.3-fpm.sock に変わったのに nginx が php8.1-fpm.sock を指したままになっているケースです。もう1つは Docker 内で、proxy_pass http://localhost:3000 がアプリではなく nginx コンテナ自身を指しているケースで、この場合は Compose のサービス名(http://app:3000)を使います。変更後は必ず sudo nginx -t と sudo systemctl reload nginx を実行してください。
4. 実例:dnsrobot.net で 502 が発生したケース
これは 2026年9月30日に私たち自身に起きたことです。新しいブログ記事をまとめて公開した後、そのうちのちょうど1本だけが nginx 1.24 経由で 502 Bad Gateway を返し、他のページはすべて正常でした。nginx の背後にある Next.js アプリにポート 3000 で直接リクエストすると、同じページが 200 OK で返ってきました。つまりアプリは正常で、失敗していたのはゲートウェイでした。
答えは nginx のエラーログの1行にありました:upstream sent too big header while reading response header from upstream。そのページのレスポンスヘッダーは 4,087 バイトあり、その大半は長い Content-Security-Policy ヘッダーと preload 用の Link ヘッダーでした。nginx はレスポンスの先頭部分(すべてのヘッダーを含む)を、proxy_buffer_size で設定されたバッファに読み込みます。この値の既定はメモリ1ページ分で、私たちのサーバーでは 4 KB でした。残りの余裕はわずか 9 バイトしかなく、ステータス行を含むヘッダー全体がバッファからあふれたのです。
修正は、アプリへプロキシしている location ブロックへの3行の追加でした:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_buffer_size 16k; # 大きなヘッダー用の領域(以前は既定の 4k)
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
}nginx -t を実行してリロードした後、そのページは 200 を返すようになりました。教訓:サイトの他の部分は正常なのに一部のページだけ 502 を返す場合は、アプリを疑う前に、そのページの大きなヘッダーや大きな Cookie といったサイズの上限を探してください。
ロードバランサー配下の Node.js:ランダムに発生する 502
AWS Application Load Balancer などのロードバランサーの背後で Node.js を動かしていて、アプリのログにエラーがないのにときどき 502 が出る場合は、keep-alive のタイムアウトを確認してください。Node の HTTP サーバーは、アイドル状態の keep-alive 接続を既定で 5秒後に閉じます(server.keepAliveTimeout、Node.js 26 以前)。一方、AWS ALB はアイドル接続を 60秒間開いたままにします。そのため、Node が接続を閉じるちょうどその瞬間にロードバランサーがその接続を再利用することがあり、そのリクエストは 502 として返ってきます。
解決策は、アプリのタイムアウトをロードバランサーより長くすることです:
const server = app.listen(3000)
// ロードバランサーのアイドルタイムアウトより長くする(ALB の既定値:60秒)
server.keepAliveTimeout = 65_000
server.headersTimeout = 66_000 // keepAliveTimeout より少し大きくするCloudflare での 502 Bad Gateway
Cloudflare を利用している場合は、まず誰がエラーページを生成したかを確認します:
Cloudflare のブランド入りページ(Browser ✓ / Cloudflare ✓ / Host ✗):Cloudflare は動作していますが、オリジンサーバーから有効な応答を得られませんでした。オリジンが稼働しているか、443/80 で待ち受けているか、ファイアウォールで Cloudflare の IP レンジをブロックしていないかを確認してください。オリジンは ポートチェッカー で直接テストできます。
シンプルなブランドなしの 502 ページ: cloudflare の記載がない場合(たとえば nginx や Apache の名前が表示される場合)、502 を生成したのはあなた自身のオリジンサーバーです。上記のサーバー側の手順を進めてください。一方、下部に「cloudflare」とだけ表示された空白のページは Cloudflare 自身が生成したもので、たとえば一時的なトラフィックの経路変更中や、オリジンが壊れた gzip コンテンツを送った場合に表示されます。
オリジンの IP が変わっていませんか? ホストを移転した場合は、Cloudflare の DNS で A レコードを更新してください。DNS Lookup で、現在世界からどう見えているかを確認できます。
Advertisement
502 エラーは SEO に悪影響がありますか?
短時間の障害なら影響はありません。Google のドキュメントによると、5xx のサーバーエラーが返されると、クローラーは一時的にクロールの速度を落とします。すでにインデックスに登録されているページは当面インデックスに残りますが、エラーが続くと、Google は最終的にそれらの URL をインデックスから削除します。
つまり、デプロイ中に数分続く 502 は無害です。一方、重要なページで何日も続く 502 や、何週間も断続的に発生する 502 は、クロールの減少や順位の低下につながる可能性があります。主要な URL を監視し、障害の後には Search Console のクロールの統計情報レポートを確認してください。
そのサイトは全員に 502 を返していますか?
DNS Robot の HTTP ヘッダーチェッカーは、当社のサーバーから任意の URL をリクエストし、正確なステータスコード、サーバーソフトウェア、すべてのレスポンスヘッダーを表示します。502 を確認する最も速い方法です。
試す HTTP ヘッダーチェッカーAdvertisement
よくある質問
あなたが到達したサーバーが nginx、Cloudflare、ロードバランサーなどのゲートウェイまたはプロキシであり、その背後のアプリケーションサーバーから不正な応答を受け取ったという意味です。プロキシ自体は動作しています。背後のアプリが停止している、クラッシュした、到達できない、またはプロキシが扱えない応答を返したのです。