Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for NGINX By James Joyner IV · · 9 min read

NGINX Error Guide: 'upstream sent too big header' (502) proxy buffer sizing

Fix NGINX upstream sent too big header (502): tune proxy_buffer_size and proxy_buffers, handle large response headers, big cookies, and FastCGI buffer limits.

  • #nginx
  • #troubleshooting
  • #errors
  • #buffers

Overview

upstream sent too big header while reading response header from upstream means the backend returned HTTP response headers larger than the buffer NGINX reserved to read them. NGINX cannot fit the headers, aborts the response, and returns 502 Bad Gateway to the client. The backend is healthy and responded — its headers are simply bigger than proxy_buffer_size (or the proxy_buffers pool) allows.

The signature line:

2026/06/23 20:31:18 [error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream, client: 203.0.113.44, server: app.example.com, request: "GET /dashboard HTTP/1.1", upstream: "http://127.0.0.1:8000/dashboard", host: "app.example.com"

This is common with apps that emit large Set-Cookie headers (big session tokens), long Location redirects with many query params, verbose security/CSP headers, or SSO flows that pack state into headers. The fix is to size NGINX’s proxy header buffers to fit — or to shrink the headers the backend sends.

Symptoms

  • Specific pages 502 (often after login or on dashboards) while most pages work.
  • error.log records upstream sent too big header.
  • The backend logs the request as a successful 200/302 — NGINX rejected it after.
  • curl directly to the backend succeeds; through NGINX it 502s.
curl -sI https://app.example.com/dashboard | head -1
HTTP/1.1 502 Bad Gateway
sudo grep "too big header" /var/log/nginx/error.log | tail -5
[error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream, upstream: "http://127.0.0.1:8000/dashboard"

Common Root Causes

1. proxy_buffer_size too small for the headers

proxy_buffer_size (default 4k/8k) holds the response status line plus all headers. A backend emitting more header bytes than that overflows it.

grep -RnE 'proxy_buffer_size|proxy_buffers' /etc/nginx/conf.d/ /etc/nginx/sites-enabled/
(no proxy_buffer_size set -> default 4k/8k applies)
[error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream

With no override, the default header buffer is too small for the page’s headers. Raise proxy_buffer_size (e.g. 16k).

Apps that store a lot in cookies (encrypted sessions, multiple flash cookies) emit big Set-Cookie headers that blow past the buffer.

curl -sI http://127.0.0.1:8000/dashboard | awk '{ print length": "$0 }' | sort -rn | head
2174: Set-Cookie: session=eyJhbGciOiJ...<very long>...; Path=/; HttpOnly
612: Set-Cookie: csrftoken=...; Path=/
[error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream

A single ~2 KB Set-Cookie plus other headers exceeds an 8k buffer. Increase the buffer or trim the cookie payload.

3. proxy_buffers pool too small (not just the first buffer)

proxy_buffer_size sizes the first buffer; the rest of the headers (and body) use the proxy_buffers pool. If both are small, very large header sets still overflow.

grep -RnE 'proxy_buffers' /etc/nginx/conf.d/app.conf
proxy_buffers 4 4k;     # only 16k total, first buffer also small
[error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream

Raise both, e.g. proxy_buffer_size 16k; proxy_buffers 8 16k;.

4. FastCGI backends need the fastcgi_* equivalents

For PHP-FPM via fastcgi_pass, the relevant directives are fastcgi_buffer_size/fastcgi_buffers, not the proxy_* ones. Setting proxy_buffer_size has no effect on a FastCGI location.

grep -RnE 'fastcgi_pass|fastcgi_buffer_size|fastcgi_buffers' /etc/nginx/conf.d/app.conf
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
(no fastcgi_buffer_size set -> default applies)
[error] 9210#9210: *70490 upstream sent too big header while reading response header from upstream, upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:"

The upstream: is fastcgi://..., so raise fastcgi_buffer_size/fastcgi_buffers for that location.

5. SSO / redirect with a giant Location or auth header

OIDC/SAML flows put long state, ID tokens, or signed parameters into a Location redirect or Authorization-related header that overflows the buffer.

curl -sI "http://127.0.0.1:8000/auth/callback?code=..." | grep -iE 'location|length' | awk '{print length": "$0}'
3120: Location: https://app.example.com/?state=<very long signed blob>&session_state=...
[error] 9210#9210: *70495 upstream sent too big header while reading response header from upstream

A 3 KB Location header overflows the default buffer during the auth redirect. Size buffers to fit the SSO flow.

6. Header buffer set in the wrong context / not reloaded

The buffer directive is set in http but a more specific location/server lacks it, or the config was edited without a reload.

grep -RnB2 'proxy_buffer_size' /etc/nginx/conf.d/ /etc/nginx/sites-enabled/
http   { proxy_buffer_size 16k; }
server { location /dashboard { proxy_buffer_size 4k; } }   # overrides smaller
[error] 9210#9210: *70498 upstream sent too big header while reading response header from upstream

A location-level proxy_buffer_size 4k; overrides the generous http-level value for the failing route.

Diagnostic Workflow

Step 1: Confirm the error and the upstream type

sudo grep "too big header" /var/log/nginx/error.log | tail -5

Note whether upstream: is http://... (use proxy_* directives) or fastcgi://... (use fastcgi_* directives). Setting the wrong family does nothing.

Step 2: Measure the actual header size from the backend

curl -sD - -o /dev/null http://127.0.0.1:8000/dashboard \
  | awk '{ total += length($0)+2 } END { print "header bytes:", total }'
curl -sI http://127.0.0.1:8000/dashboard | awk '{print length": "$0}' | sort -rn | head

This tells you how big the headers are and which one (often Set-Cookie or Location) is the offender, so you can size the buffer with headroom.

Step 3: Check current buffer settings and their context

grep -RnB2 -E 'proxy_buffer_size|proxy_buffers|fastcgi_buffer_size|fastcgi_buffers' \
  /etc/nginx/conf.d/ /etc/nginx/sites-enabled/

Find the effective value for the failing location (most specific block wins) and confirm it is smaller than the measured header size.

Step 4: Raise the right buffers with headroom

For an HTTP/proxy upstream, in the http, server, or failing location:

proxy_buffer_size   16k;
proxy_buffers       8 16k;
proxy_busy_buffers_size 32k;

For a FastCGI/PHP upstream:

fastcgi_buffer_size 16k;
fastcgi_buffers     8 16k;

Pick a first-buffer size comfortably above the measured header bytes.

Step 5: Validate and reload

sudo nginx -t
sudo systemctl reload nginx
curl -sI https://app.example.com/dashboard | head -1

nginx -t must pass; after reload the page should return 200/302 instead of 502.

Example Root Cause Analysis

After enabling SSO, the /dashboard page 502s for every logged-in user. Anonymous pages work. The backend logs show a clean 200 for the same request.

The error log:

[error] 9210#9210: *70488 upstream sent too big header while reading response header from upstream, upstream: "http://127.0.0.1:8000/dashboard"

Measuring the backend headers directly:

curl -sI http://127.0.0.1:8000/dashboard | awk '{print length": "$0}' | sort -rn | head -3
2174: Set-Cookie: session=eyJhbGciOiJ...<encrypted SSO session>...; Path=/; HttpOnly; Secure
512:  Content-Security-Policy: default-src 'self'; ...

The SSO session cookie is ~2.1 KB; combined with CSP and other headers the response header block exceeds NGINX’s default 8k header buffer, so NGINX rejects it with 502. No proxy_buffer_size is set, so the default applies.

Fix: raise the proxy header buffers (HTTP upstream), validate, and reload:

location /dashboard {
    proxy_buffer_size   16k;
    proxy_buffers       8 16k;
    proxy_busy_buffers_size 32k;
    proxy_pass http://127.0.0.1:8000;
}
sudo nginx -t
sudo systemctl reload nginx
curl -sI https://app.example.com/dashboard | head -1
HTTP/1.1 200 OK

The dashboard loads. (Trimming the session cookie would also help long-term.)

Prevention Best Practices

  • Size proxy header buffers for your largest realistic header set (SSO sessions, CSP, multiple Set-Cookies) with headroom — proxy_buffer_size 16k; is a safe baseline for apps with big cookies.
  • Match the directive family to the upstream: proxy_* for proxy_pass, fastcgi_* for fastcgi_pass. Setting the wrong one silently does nothing.
  • Keep response headers lean: store session state server-side and send a short session ID instead of packing kilobytes into a cookie, which avoids the problem at the source.
  • Audit for location-level buffer overrides that undercut a generous http-level value, and always reload after editing.
  • Add upstream sent too big header to your error.log alerting so a new header-heavy feature is caught in staging, not by users hitting 502s.
  • For triage of a header-size 502 wave, the free incident assistant can correlate the failing route with the oversized header. More fixes live in the NGINX guides.

Quick Command Reference

# Confirm error + upstream type (http vs fastcgi)
sudo grep "too big header" /var/log/nginx/error.log | tail -5

# Measure backend header size and the biggest header
curl -sD - -o /dev/null http://127.0.0.1:8000/dashboard \
  | awk '{ total += length($0)+2 } END { print "header bytes:", total }'
curl -sI http://127.0.0.1:8000/dashboard | awk '{print length": "$0}' | sort -rn | head

# Inspect current buffers and their context
grep -RnB2 -E 'proxy_buffer_size|proxy_buffers|fastcgi_buffer_size|fastcgi_buffers' \
  /etc/nginx/conf.d/ /etc/nginx/sites-enabled/

# After raising buffers: validate and reload
sudo nginx -t && sudo systemctl reload nginx
curl -sI https://app.example.com/dashboard | head -1

Conclusion

upstream sent too big header is a 502 caused by response headers that do not fit NGINX’s proxy header buffer. The usual root causes:

  1. proxy_buffer_size (default 4k/8k) is smaller than the headers.
  2. Large Set-Cookie/session headers overflow the buffer.
  3. The proxy_buffers pool is too small for big header sets.
  4. A FastCGI backend needs fastcgi_buffer_size/fastcgi_buffers, not proxy_*.
  5. An SSO redirect with a giant Location/auth header.
  6. A buffer override in the wrong context, or a config not reloaded.

Measure the backend’s real header size, raise the matching buffer family with headroom, then nginx -t and reload. Long-term, keep headers small — server-side sessions beat kilobyte cookies.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.