
環境
Ubuntu:24.04
PHP:8.2
Laravel:11.x
起こったこと
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が使用するメモリ量が増加し、サーバーリソースを圧迫する可能性があります。まずはエラーが出なくなる最小限の増加から試し、サーバーの負荷状況を見ながら調整してください。
設定変更後の手順
- Nginx設定ファイルを保存: 変更したNginx設定ファイルを保存します。
- 設定ファイルのテスト:
このコマンドで構文エラーがないかを確認します。sudo nginx -t
test is successful
と表示されればOKです。 - Nginxのリロード:
Nginxサービスをリロードして、新しい設定を適用します。sudo systemctl reload nginx
これで、Nginxが大きなHTTPレスポンスヘッダーを適切に処理できるようになり、「upstream sent too big header
」エラーは解消されるはずです。
根本的な解決策:Laravelアプリケーション側の最適化
Nginxの設定でエラーを抑制できますが、Laravelアプリケーション側で不必要に大きなヘッダーが生成されている場合は、そちらの最適化も検討することをお勧めします。
- セッションデータの見直し:
- クッキーに保存しているセッションデータが大きすぎる場合、データベースやRedisなどのサーバーサイドストレージにセッションを保存するようにLaravelの設定を変更することを検討してください。これにより、クッキーにセッションIDのみが保存されるため、クッキーのサイズを大幅に削減できます。Laravelのセッション設定は
config/session.php
で変更可能です。
- クッキーに保存しているセッションデータが大きすぎる場合、データベースやRedisなどのサーバーサイドストレージにセッションを保存するようにLaravelの設定を変更することを検討してください。これにより、クッキーにセッションIDのみが保存されるため、クッキーのサイズを大幅に削減できます。Laravelのセッション設定は
- クッキーの管理:
- アプリケーションが設定しているクッキーの数や、個々のクッキーのサイズを減らせないかレビューします。不要なクッキーは削除しましょう。
- カスタムヘッダーの確認:
- アプリケーションがレスポンスに含めているカスタムHTTPヘッダーが多すぎないか、または内容が大きすぎないかを確認します。
Nginxの設定調整で当面のエラーは解消されますが、アプリケーションの効率性を高めるためにも、Laravel側のヘッダー生成ロジックを見直すことは良いプラクティスです。