HTTP 431 Request Header Fields Too Large
HTTP 431 Request Header Fields Too Large means the server refused to process the request because the total size of the HTTP request headers exceeded the server’s configured limit. The two overwhelmingly common causes are: accumulated cookies in the Cookie header that have grown too large over time, and JWT access tokens carrying large payloads in the Authorization header. From the user’s perspective, the site simply stops working. From the server’s logs, you see 431 responses hitting a specific user or session.
Quick reference
| Code | 431 |
|---|---|
| Name | Request Header Fields Too Large |
| Category | 4xx Client Error |
| Specification | RFC 6585 §5 (also RFC 9110) |
| IANA status | Assigned |
| Cacheable? | Not cached |
| Retryable? | Yes, after reducing header size |
Cookie accumulation: the most common cause
Cookies are sent by the browser in the Cookie header on every request to the matching domain and path. A site that sets many cookies — session token, CSRF token, A/B test assignment, analytics identifiers, consent preferences, feature flags, language preference — can accumulate 3–5KB of cookie data per request without anyone noticing. Add third-party cookies from SDKs embedded in the page (analytics, chat, tracking) and the total can easily exceed nginx’s default 8KB buffer.
The problem is often invisible during development (developers have fresh browsers with few cookies) and only surfaces for users who have visited the site many times, or after a deployment that added new cookies on top of existing ones.
Diagnose with browser DevTools: open Network tab, click a failing request, and look at the Request Headers section. Find the Cookie header and check its total size. A Cookie header over 4KB on a simple request is a warning sign; over 7KB will trigger 431 on nginx with default settings.
# nginx default: 4 header buffers of 8KB each # A single header (like Cookie) must fit in one buffer large_client_header_buffers 4 8k;
JWT bloat in Authorization headers
JWTs are base64url-encoded JSON objects. A minimal JWT (sub, iat, exp) is roughly 200 bytes. A JWT that includes user roles, permissions, organization memberships, feature flags, and profile data can reach 3–5KB. Sent as Authorization: Bearer <token> on every API request, a 4KB JWT consumes half of nginx’s default header buffer before any other headers are counted.
The fix is to keep JWT payloads small. The token should contain only the claims the server needs to make an authorization decision without additional lookups: at minimum, subject identifier, issued-at, expiry, and a scope or role list. Large data sets (full profile, all group memberships, detailed permissions) should be stored server-side and looked up by the subject identifier from the token, not embedded in the token itself.
# Check your JWT payload size # Paste the token at jwt.io or decode locally: echo "<token_middle_part>" | base64 -d | python3 -m json.tool | wc -c
Server-side header size limits
nginx:
http {
# Allow larger headers (increase from default 4 8k)
large_client_header_buffers 8 16k;
server {
# Or per-server if only specific vhosts need it
large_client_header_buffers 8 16k;
}
}
After editing nginx.conf, test and reload: nginx -t && systemctl reload nginx
Apache:
# In httpd.conf or .htaccess LimitRequestFieldSize 16384 # bytes per header field (default 8190) LimitRequestFields 200 # max number of header fields
Node.js (http module):
const server = http.createServer({ maxHeaderSize: 16384 }, handler);
// Or via CLI flag:
// node --max-http-header-size=16384 app.js
AWS Application Load Balancer: ALB has a fixed 16KB limit on total request header size and 8KB per individual header field. This cannot be configured. If headers exceed this, use a custom Nginx in front or reduce header sizes.
Fix cookie bloat at the application level
Increasing the server limit treats the symptom. The root cause fix is reducing cookie size:
Audit existing cookies: In DevTools (Application → Cookies), list all cookies and their sizes. Identify which cookies are large, which have no expiry (session cookies accumulate per browser session), and which are set by third-party SDKs that could be consolidated.
Consolidate session data: Instead of 10 separate small cookies, use a single session cookie that maps to a server-side session store (Redis, database). The browser sends one small session ID; the server looks up all session state server-side. This is the most robust fix for cookie bloat.
Set cookie expiry and size limits: Cookies with no Max-Age or Expires attribute persist until the browser closes. Set explicit expiry. For analytics and tracking cookies, use SameSite=Strict or SameSite=Lax with short lifetimes.
Scope cookies carefully: A cookie with Domain=.example.com and Path=/ is sent to every subdomain and every path. Scope cookies to the minimum domain and path needed. A cookie only needed by the API should not be sent to the marketing subdomain.
Remove unused SDK cookies: Third-party analytics and chat SDKs often set cookies without the site owner realizing. Audit which third-party scripts are setting cookies and remove or configure those not needed.
Diagnosing 431 in production
# nginx access log format
# $request_length includes headers + body in bytes
log_format main '$remote_addr - $status $request_length "$request_uri"';
# Find requests with 431 status
grep ' 431 ' /var/log/nginx/access.log | awk '{print $3, $4, $5}' | head -20
# Check if specific users/sessions are affected
grep ' 431 ' /var/log/nginx/access.log | grep -o 'session=[^;]*' | sort | uniq -c | sort -rn
Systematic 431 across all users (not just some) indicates a new deployment introduced oversized headers: a new cookie added to all responses, a JWT payload that grew with a new claim, or a new custom header added to all API requests. Check your deployment timeline against when 431 errors started appearing.
431 vs 413 vs 414 vs 400
| Code | What is too large | Common cause |
|---|---|---|
| 431 | Request headers | Cookie accumulation, JWT bloat, large custom headers |
| 413 | Request body | File upload, large JSON payload, bulk data POST |
| 414 | Request URI | Query string with many filter params, base64 in URL |
| 400 | Request format | Malformed syntax in headers or URL, not a size issue |
Frequently asked questions
What causes HTTP 431?
The two most common causes are cookie accumulation (many small cookies add up to exceed the server header size limit, typically 8KB in nginx) and oversized JWT tokens (JWTs that embed large user profiles or role lists in the Authorization header). Less common causes include large custom headers in API requests.
How do I fix HTTP 431 as a user?
Clear your browser cookies for the affected domain, then reload. If the problem recurs, the site is setting too many or too large cookies and the fix is on the server side.
What is the default header size limit in nginx?
nginx default: large_client_header_buffers 4 8k, which allows up to 4 header lines of 8KB each. The total Cookie header must fit within one 8KB buffer. To increase: set large_client_header_buffers 8 16k in the server or http block.
What is the difference between 431 and 413?
431 is about request headers being too large. 413 is about the request body being too large. Headers include Cookie, Authorization, and custom X- headers. The body is the payload sent with POST/PUT requests. Each has separate size limits configured independently in the server.
Related guides
HTTP 413 Content Too Large · HTTP 414 URI Too Long · HTTP 400 Bad Request
Comparisons
Standards reference
Definitions from the IANA HTTP Status Code Registry and RFC 6585 §5. Human-readable guidance by ErrorLookup. · HTTP 431 quick reference →