症状
nginxのエラーログに connect() failed (111: Connection refused) while connecting to upstream が出力される。
クライアントには 502 Bad Gateway または 504 Gateway Timeout が返される。
結論:まずこれを確認
- バックエンドサーバー(upstream)のプロセスが起動しているか
- nginx設定の
proxy_passで指定したポートが正しいか - バックエンドが指定アドレス(127.0.0.1 or 0.0.0.0)でリッスンしているか
トラブルシューティングフロー
flowchart TD
A[エラーログを確認] --> B{upstreamのホスト:ポートを特定}
B --> C{バックエンドプロセスは起動している?}
C -->|No| D[バックエンドを起動する]
C -->|Yes| E{リッスンポートは正しい?}
E -->|No| F[ポート設定を修正]
E -->|Yes| G{リッスンアドレスは正しい?}
G -->|No| H[bind addressを修正]
G -->|Yes| I{ファイアウォールは許可?}
I -->|No| J[ファイアウォール設定を修正]
I -->|Yes| K[バックエンドのログを確認]
よくある原因
- バックエンドプロセスが停止している — デプロイ後やサーバー再起動後に起動していない
- ポート番号の不一致 — nginx設定とバックエンドの実際のリッスンポートが異なる
- リッスンアドレスの問題 — バックエンドが
127.0.0.1のみでリッスンし、nginxが別IPでアクセスしている - ソケットファイルの問題 — UNIXソケット使用時にパーミッションまたはパスが間違っている
- ファイアウォールによるブロック — iptables/firewalld/ufw がローカル通信をブロックしている
- SELinuxによるブロック — SELinux が httpd_can_network_connect を拒否している
- バックエンドの起動遅延 — nginx起動時にバックエンドがまだ準備できていない
確認手順
ステップ1: エラーログからupstream情報を確認する
sudo tail -50 /var/log/nginx/error.log | grep "upstream"
🔍 チェックポイント: upstream: "http://127.0.0.1:3000/..." のようにホストとポートが表示される
ステップ2: バックエンドプロセスの起動状態を確認する
# systemdで管理している場合
sudo systemctl status <サービス名>
# プロセスを直接確認
ps aux | grep <プロセス名>
🔍 チェックポイント: active (running) または該当プロセスが表示される
停止している場合:
sudo systemctl start <サービス名>
ステップ3: リッスンポートを確認する
# 特定ポートの使用状況を確認
sudo ss -tlnp | grep <ポート番号>
# または netstat を使用
sudo netstat -tlnp | grep <ポート番号>
🔍 チェックポイント: 該当ポートでバックエンドプロセスがLISTEN状態になっている
出力例:
LISTEN 0 511 127.0.0.1:3000 *:* users:(("node",pid=1234,fd=18))
ステップ4: リッスンアドレスを確認する
sudo ss -tlnp | grep <ポート番号>
🔍 チェックポイント:
127.0.0.1:3000— ローカルホストからのみ接続可能0.0.0.0:3000または*:3000— すべてのインターフェースから接続可能
nginx が proxy_pass http://127.0.0.1:3000 を指定している場合、バックエンドも 127.0.0.1 でリッスンしている必要がある。
ステップ5: UNIXソケットを使用している場合
# ソケットファイルの存在確認
ls -la /var/run/<アプリ名>/<ソケット名>.sock
# nginx設定のソケットパスを確認
grep -r "proxy_pass.*unix:" /etc/nginx/
🔍 チェックポイント: ソケットファイルが存在し、nginxユーザーに読み書き権限がある
パーミッション修正例:
sudo chmod 660 /var/run/<アプリ名>/<ソケット名>.sock
sudo chown <アプリユーザー>:nginx /var/run/<アプリ名>/<ソケット名>.sock
ステップ6: ファイアウォールを確認する
# iptables
sudo iptables -L -n | grep <ポート番号>
# firewalld
sudo firewall-cmd --list-all
# ufw
sudo ufw status verbose
🔍 チェックポイント: ローカル通信(lo インターフェース)が許可されている
通常、ローカルホスト間通信はデフォルトで許可されているが、厳格なルールが設定されている場合は確認が必要。
ステップ7: SELinuxを確認する(RHEL/CentOS系)
# SELinuxの状態確認
getenforce
# httpd_can_network_connect の確認
getsebool httpd_can_network_connect
🔍 チェックポイント: httpd_can_network_connect --> on になっている
許可する場合:
sudo setsebool -P httpd_can_network_connect 1
ステップ8: nginx設定を確認する
# 設定ファイルの文法チェック
sudo nginx -t
# proxy_pass の設定確認
grep -r "proxy_pass" /etc/nginx/sites-enabled/
# または
grep -r "proxy_pass" /etc/nginx/conf.d/
🔍 チェックポイント: proxy_pass のホスト・ポートがバックエンドの実際のリッスン設定と一致している
NG行動(やってはいけないこと)
- バックエンドを確認せずnginxだけ再起動する — 原因がバックエンド側にある場合は解決しない
- SELinuxを無効化する — セキュリティリスクが高い。必要な権限のみ許可する
- ファイアウォールを完全に停止する — 必要なポートのみ許可する
- エラーログを確認せずに設定を変更する — 原因を特定してから対処する
- 本番環境でnginx -s reloadではなくrestartする — 接続中のリクエストが切断される
よくある質問(FAQ)
Q1: 特定のURLだけでこのエラーが出る場合は?
A: 複数のupstreamを設定している場合、該当URLに対応するlocationブロックの proxy_pass 設定を確認する。upstreamごとにバックエンドの状態が異なる可能性がある。
Q2: 間欠的にこのエラーが発生する場合は?
A: バックエンドの過負荷、メモリ不足によるプロセス再起動、またはコネクションプールの枯渇が考えられる。バックエンドのリソース使用状況とログを確認する。
Q3: Dockerコンテナをupstreamにしている場合は?
A: コンテナのネットワーク設定を確認する。docker network inspect でIPアドレスを確認し、コンテナが起動しているか docker ps で確認する。
関連するエラー・症状
- (関連記事準備中)
- (関連記事準備中)
- (関連記事準備中)
解決しない場合
公式ドキュメント
確認すべきログファイル
/var/log/nginx/error.log— nginxエラーログ- バックエンドアプリケーションのログ
/var/log/messagesまたは/var/log/syslog— システムログ/var/log/audit/audit.log— SELinux監査ログ(RHEL系)
次に調べるキーワード
nginx upstream connection refusednginx proxy_pass not workingnginx 502 upstream<バックエンドアプリ名> not listening