What does HTTP status 431 Request Header Fields Too Large mean, when is a server supposed to send it, and why do many real servers send 400 Bad Request in the same situation instead?
answer
- 431 = header section too large (RFC 6585)
- Body should name the offending field
- nginx/Tomcat often answer 400 instead
- 413 = body, 414 = URI, 431 = headers
- Retrying unchanged never helps
basics
~20 s431 means the request's header fields are too large — either one field or the whole set — so the server refused to process it. It is the correct code, but many servers (and proxies) reject oversized headers with 400 Bad Request or just close the connection, because the failure happens mid-parse.
solid answer
~60 s`431 Request Header Fields Too Large` is defined in RFC 6585. It says the server declines to process the request because the header section is too large — either the total exceeds the server's budget, or one individual field does. The response body should say which field is the problem so the client can fix it, and the fix is always "send smaller headers", not "retry": a blind retry loop reproduces the same failure. In practice you will often see something else. The parser hits its buffer limit before the message is complete, so the server may not have a usable request to respond to at all. nginx logs "client sent too long header line" and answers `400 Bad Request`. Tomcat's `maxHttpHeaderSize` overflow surfaces as a 400. Node.js is one of the well-behaved ones and returns 431. Some intermediaries simply reset the connection, which the client sees as a network error or a 502 from the tier above. So the diagnostic lesson is: **treat 400, 431, and unexplained connection resets on large requests as the same symptom.**
code
http · 9 linesGET /dashboard HTTP/1.1
Host: app.example.com
Cookie: session=...; analytics=...; <18 KB of cookies>
HTTP/1.1 431 Request Header Fields Too Large
Content-Type: text/plain
Connection: close
The Cookie header exceeds the 8192-byte limit.go deeper
Know what 431 means, that it concerns headers rather than the body, and that the fix is to send smaller headers.
Add that many servers answer 400 or reset the connection instead, and distinguish 413, 414, and 431 by which part of the request they govern.
Explain why the failure happens mid-parse and never reaches the application, how to identify it from edge logs, and the cookie-clearing remediation that breaks retry loops.
Treat it as a platform contract question: which tier is authoritative for the header budget, what error clients see, and whether the error page can self-heal the client's cookie state.
## The status code `431 Request Header Fields Too Large` was added by RFC 6585 ("Additional HTTP Status Codes"), the same document that introduced `428 Precondition Required`, `429 Too Many Requests`, and `511 Network Authentication Required`. It is a 4xx code, meaning the client's message is the problem and repeating it unchanged will fail again. Its definition covers two cases: - the **header section as a whole** is too large, or - a **single header field** is too large. The specification suggests the response body identify which field caused the rejection — for example, "the Cookie header is too long" — because the client cannot otherwise guess what to shrink. ## Why 431 exists at all A server must buffer the header section before it can act on the request: it needs the method, the target, the Host, the content framing. That buffer is allocated per connection, and header parsing happens before authentication, routing, or any application logic. If a server accepted unlimited headers it would let unauthenticated clients allocate unbounded memory — a cheap denial of service. So every server caps the header section, and 431 is the polite way to say the cap was exceeded. ## Why you often see 400 instead The honest answer is timing and legacy. Header parsing fails **mid-message**. At that point the server may have no Host, no request target, and no idea whether the client will keep sending bytes. Producing any response requires abandoning the rest of the request and usually closing the connection. Different implementations made different choices, and most predate RFC 6585: - **nginx** answers `400 Bad Request` with an error-log line like `client sent too long header line` or `request header is too big`. It uses an internal-only code (494) for logging, but what the client sees is 400 by default. You can remap it with `error_page 494 =431 /431.html`. - **Apache httpd** returns 400 when `LimitRequestFieldSize` or `LimitRequestLine` is exceeded, and 431 in some newer configurations. - **Tomcat / Spring Boot** exceeding `maxHttpHeaderSize` surfaces as a 400. - **Node.js** returns 431 when `--max-http-header-size` is exceeded — it is the reference example of the code in the wild. - **CDNs and load balancers** vary; several simply reset the connection, which the next tier reports as 502 Bad Gateway. Because of that spread, "is it 400 or 431?" is a weak signal. Header-size failures are better identified by the *shape* of the incident: large or authenticated requests fail while small or anonymous ones succeed, and the application logs show nothing because the request never reached the application. ## What a client should do Nothing automatic helps. 431 is not retryable in the useful sense; the request must be made smaller. Realistic client-side responses: - drop or shrink cookies (a browser can be told to clear cookies for the site), - stop sending a giant bearer token in a header and use an opaque session identifier, - move data out of headers and into the request body where the limit is separate and far larger, - shorten long URLs, since the request line usually shares the same budget. A subtle trap: if the *response* to 431 sets cookies or the app redirects to a login page that sets more cookies, the client can enter a loop where every attempt is oversized. Serving a 431 page that explicitly clears the offending cookies (`Set-Cookie: big=; Max-Age=0; Path=/`) is a real remediation technique. ## Relationship to other size codes - **413 Content Too Large** (formerly Payload Too Large) is about the request **body**, governed by different settings (`client_max_body_size`, `maxPostSize`, multipart limits). - **414 URI Too Long** is about the request **target**. Many servers count the request line against the same buffer as headers, so a long URL and a big cookie compete for one budget. - **431** is the header section. Knowing which of the three you are looking at immediately tells you which knob to turn. ## HTTP/2 and HTTP/3 The limit does not disappear when headers are compressed. HTTP/2 and HTTP/3 endpoints advertise `SETTINGS_MAX_HEADER_LIST_SIZE`, computed over the **uncompressed** name/value list plus per-field overhead. Exceeding it typically produces a stream reset (`RST_STREAM` with `ENHANCE_YOUR_CALM` or a protocol error) or a 431, depending on the server. HPACK and QPACK save bandwidth, not budget.
- How would you distinguish a 431/400 caused by oversized headers from an ordinary malformed-request 400?Look at where the log entry appears and how the failure correlates with request size. A header-size rejection is logged by the front-end server or proxy with a message like "too long header line" and never reaches the application, so application access logs have no matching entry. It also correlates with authenticated or long-session users and disappears in a private browsing window, while a genuine malformed-request 400 reproduces regardless of cookie state.
- A client gets 431 and its retry logic keeps retrying. Is that reasonable?No. 431 is a client-side 4xx: the same request will fail identically because nothing about the server changes. Retrying wastes capacity and can amplify an incident. The correct handling is to fail fast and shrink the request — drop cookies, use an opaque session reference instead of a large token, or move data into the body.
saying these in an interview costs you the question
- Confusing 431 with 413 (body too large) or 414 (URI too long).
- Assuming a 431 is transient and safe to retry.
- Expecting every server to send 431; nginx and Tomcat commonly send 400 for the same condition.
- Believing header compression in HTTP/2 removes the limit — the budget is measured uncompressed.
- Looking only in application logs; the request is rejected before the application ever sees it.