Nginxエラーの解決: upstream prematurely closed connection while reading response header

intermediate Nginx2026-06-23| Linux (Ubuntu/CentOS/Debian), Nginx 1.18+, バックエンド (Node.js, Gunicorn, PHP-FPM, Go)

Error Message

upstream prematurely closed connection while reading response header from upstream
#nginx#upstream#timeout#backend-crash

エラーメッセージ

Nginxのエラーログ(通常は /var/log/nginx/error.log にあります)を確認すると、以下のような特定の行に遭遇することがあります。

[error] 1234#0: *5678 upstream prematurely closed connection while reading response header from upstream, client: 1.2.3.4, server: example.com, request: "POST /api/data HTTP/1.1", upstream: "http://127.0.0.1:8080/api/data"

主な原因

このエラーは、Nginxがバックエンド(アップストリーム)への接続とリクエストの送信に成功したものの、バックエンドがHTTPレスポンスヘッダーの送信を完了する前にTCP接続を終了したことを示しています。これは通常、以下の4つの理由で発生します。

  • バックエンドのクラッシュ: リクエストの処理中に、アプリケーションプロセス(Node.js, Python, PHPなど)がクラッシュしたか、OOM(メモリ不足)により強制終了された。
  • タイムアウトの不整合: バックエンド側のタイムアウト設定がNginxよりも短く、処理の途中で接続が切断された。
  • バッファオーバーフロー: バックエンドから送信されたレスポンスヘッダーが、Nginxの現在のバッファ設定に対して大きすぎる。
  • Keep-aliveの問題: Nginxがまだ有効であると認識していた持続的接続を、バックエンド側が閉じてしまった。

ステップ別の修正方法

1. バックエンドアプリケーションの状態を確認する

最も一般的な原因は、リクエストの途中でバックエンドサービスが失敗することです。すぐにアプリケーションログを確認してください。例えば、systemdを使用している場合は以下の通りです。

# サービスの状態と最近のログを確認
journalctl -u my-backend-service -n 50 --no-pager

セグメンテーション違反(Segmentation Fault)、メモリ不足(OOM)エラー、または未処理の例外を探します。バックエンドがクラッシュしている場合は、Nginxの設定をいじる前に、コードを修正するかサーバーのRAMを増設してください。

2. プロキシバッファサイズを増やす

アプリケーションが大きなCookieや多くのカスタムヘッダーを送信する場合、ヘッダーがバッファサイズを超えるとNginxが接続を切断することがあります。location または http ブロックに以下のディレクティブを追加してください。

location / {
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_pass http://your_backend;
}

保存後、Nginxのテストとリロードを行います。

nginx -t && systemctl reload nginx

3. Keep-Alive設定を同期させる

バックエンドがすでにタイムアウトして閉じた接続をNginxが再利用しようとすると、このエラーが発生します。Nginxとバックエンドの間で、接続を維持する時間(Keep-alive)の認識を一致させてください。proxy_keepalive を無効にするか、バックエンドのタイムアウトをNginxよりも長く設定します。

upstream ブロックの設定例:

upstream my_backend {
    server 127.0.0.1:8080;
    keepalive 32;
    keepalive_requests 100;
    keepalive_timeout 60s;
}

エラーが解消されない場合は、proxy_http_version 1.1;proxy_set_header Connection ""; を設定して、Keep-aliveを適切に処理するように試みてください。

4. バックエンドの実行タイムアウトを増やす

バックエンドの応答に時間がかかりすぎると、バックエンド内部のタイムアウト(PHPの max_execution_time や Gunicornの timeout など)に達してソケットが閉じられることがあります。これらの値をNginxの proxy_read_timeout に合わせて増やしてください。

Nginxの設定例:

location /api/ {
    proxy_read_timeout 300s;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_pass http://your_backend;
}

動作確認

修正を確認するには、失敗していた特定のエンドポイントに対して curl で負荷をかけます。

curl -I -X POST https://example.com/api/data

リクエストを実行しながら、リアルタイムでエラーログを監視します。

tail -f /var/log/nginx/error.log

HTTP 502/504エラーが消え、新しい「prematurely closed」のログが表示されなくなれば、設定は安定しています。

予防策

  • モニタリング: 5xxステータスコードやバックエンドプロセスの再起動に関するアラートを設定する。
  • リソース制限: バックエンドが同時接続を処理するのに十分なファイル記述子(ulimit -n)を持っていることを確認する。
  • 正常なシャットダウン(Graceful Shutdown): デプロイ中にアクティブな接続が切断されないよう、アプリケーションがSIGTERMを適切に処理できるようにする。

Related Error Notes