ソフトウェアをリリースしました

かいふく という訪問介護の副業に特化した求人サイトを公開しています。

お近くの介護資格保有者にご紹介頂けると嬉しいです 👏

https://kai-fuku.com/

このサイトにはプロモーションが含まれます

Nginxの「upstream sent too big header」エラーを解決する:LaravelとPHP-FPM環境での対処法

環境

Ubuntu:24.04
PHP:8.2
Laravel:11.x

やんやん

プログラマーとしてLEMP環境に主に生息しており、DevOps 的な立ち回りをしながらご飯を食べている当ブログの管理人のやんやんと申します。
最近はTmux使うのを辞めました。

起こったこと

NginxをWebサーバーとして、LaravelアプリケーションとPHP-FPMを連携させている環境で、ある日突然 upstream sent too big header while reading response header from upstream というエラーがNginxのエラーログに表示され、Webサイトが正常に表示されなくなリマした…

調べていくと、このエラーは、PHP-FPM(アップストリームサーバー)がNginxに返そうとしたHTTPレスポンスヘッダーのサイズが、Nginxが受け入れられる設定値の上限を超えてしまった場合に発生します。

特にLaravelのような動的なアプリケーションでは、セッション情報やクッキーの肥大化が原因で発生しやすい問題とのことでやんす。

エラーが起きる原因は?

NginxがWebサーバーとしてクライアントからのリクエストを受け取り、それをバックエンドのPHP-FPM(FastCGIプロセス)に渡して処理してもらいます。

PHP-FPMが処理を終えてNginxに応答を返す際、そのHTTPレスポンスにはヘッダー情報が含まれます。このヘッダー情報がNginxが設定しているバッファのサイズを超えると、エラーが発生してしまいます。

主な原因として、以下のようなものが挙げられます。

  • セッションデータの肥大化: Laravelなどのフレームワークでセッションをクッキーベースで管理している場合、ユーザーが多くの情報をセッションに保存したり、ショッピングカートに大量のアイテムを追加したりすると、クッキーのサイズが大きくなります。この大きなクッキー情報がレスポンスヘッダーに含まれることで、上限を超えてしまうことがあります。
  • 多数のクッキーやカスタムヘッダー: アプリケーションが非常に多くのクッキーを設定している、または独自のカスタムヘッダーを大量に追加している場合も、ヘッダー全体のサイズが大きくなります。
  • リダイレクトループ: 不適切なリダイレクト設定により、ブラウザが何度もリダイレクトを繰り返す際、そのたびに新しいクッキーやヘッダーが付与され、最終的にヘッダーが大きくなってしまうケースも考えられます。

解決策:Nginxの設定を調整する

最も手軽で直接的な解決策は、Nginxが受け入れられるヘッダーバッファのサイズを増やすことです。

Nginxの設定ファイル(通常は /etc/nginx/nginx.conf か、サイト固有の .conf ファイル)を開き、http ブロック内、または対象の server ブロック内に以下のディレクティブを追加または調整します。http ブロックに記述すると、すべてのバーチャルホストに適用されます。

http {
    # ... 他の http ブロック内の設定 ...

    # upstream sent too big header エラー対策
    # PHP-FPM(FastCGI)からのレスポンスヘッダーに対応するため、fastcgi_ のディレクティブを設定します。
    # 必要に応じて proxy_ のディレクティブも設定しますが、PHP-FPMの場合はfastcgi_を優先します。
    fastcgi_buffer_size 128k;   # FastCGIヘッダーバッファの初期サイズ。デフォルトは4k/8k。
    fastcgi_buffers     4 256k; # 256KBのバッファを4つ用意。合計1MB。

    # 必要に応じて、もしプロキシとして使用している場合も考慮するなら、こちらも設定
    # proxy_buffer_size   128k;
    # proxy_buffers       4 256k;
    # proxy_busy_buffers_size 256k;

    # ... 他の http ブロック内の設定 ...
}

 

ディレクティブの解説

  • fastcgi_buffer_size: NginxがFastCGIからのレスポンスヘッダーを読み込むための最初のバッファサイズを指定します。デフォルト値(通常は 4k または 8k)よりも大きな値(例:128k)を設定することで、大きなヘッダーにも対応できるようになります。
  • fastcgi_buffers: ヘッダーを含むレスポンス全体をバッファリングするためのバッファの数とサイズを設定します。上記の例では、256KBのバッファを4つ使用し、合計で1MBのバッファスペースを確保します。

注意点: これらの値を必要以上に大きくしすぎると、Nginxが使用するメモリ量が増加し、サーバーリソースを圧迫する可能性があります。まずはエラーが出なくなる最小限の増加から試し、サーバーの負荷状況を見ながら調整してください。

設定変更後の手順

  1. Nginx設定ファイルを保存: 変更したNginx設定ファイルを保存します。
  2. 設定ファイルのテスト:
    sudo nginx -t

     

    このコマンドで構文エラーがないかを確認します。test is successful と表示されればOKです。

  3. Nginxのリロード:
    sudo systemctl reload nginx
    

     

    Nginxサービスをリロードして、新しい設定を適用します。

これで、Nginxが大きなHTTPレスポンスヘッダーを適切に処理できるようになり、「upstream sent too big header」エラーは解消されるはずです。

根本的な解決策:Laravelアプリケーション側の最適化

Nginxの設定でエラーを抑制できますが、Laravelアプリケーション側で不必要に大きなヘッダーが生成されている場合は、そちらの最適化も検討することをお勧めします。

  • セッションデータの見直し:
    • クッキーに保存しているセッションデータが大きすぎる場合、データベースやRedisなどのサーバーサイドストレージにセッションを保存するようにLaravelの設定を変更することを検討してください。これにより、クッキーにセッションIDのみが保存されるため、クッキーのサイズを大幅に削減できます。Laravelのセッション設定は config/session.php で変更可能です。
  • クッキーの管理:
    • アプリケーションが設定しているクッキーの数や、個々のクッキーのサイズを減らせないかレビューします。不要なクッキーは削除しましょう。
  • カスタムヘッダーの確認:
    • アプリケーションがレスポンスに含めているカスタムHTTPヘッダーが多すぎないか、または内容が大きすぎないかを確認します。

Nginxの設定調整で当面のエラーは解消されますが、アプリケーションの効率性を高めるためにも、Laravel側のヘッダー生成ロジックを見直すことは良いプラクティスです。

おすすめの記事