症状

nginxのエラーログに connect() failed (111: Connection refused) while connecting to upstream が出力される。

クライアントには 502 Bad Gateway または 504 Gateway Timeout が返される。


結論:まずこれを確認

  1. バックエンドサーバー(upstream)のプロセスが起動しているか
  2. nginx設定の proxy_pass で指定したポートが正しいか
  3. バックエンドが指定アドレス(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 refused
  • nginx proxy_pass not working
  • nginx 502 upstream
  • <バックエンドアプリ名> not listening