431 Request Header Fields Too Large (tested)
HTTP 431 Request Header Fields Too Large means the server refused the request because its headers were too big. On a dev machine the usual cause is not your code: it is a pile of cookies on localhost left by other apps, because cookies ignore the port. We measured the exact Node.js limit and reproduced the localhost case in Chromium.
1. The exact Node.js limit
Node.js 24 has a default maxHeaderSize of 16 KB. We sent curl requests with one extra header X: aaaa... and bisected its length:
| Server | Largest value that got 200 | Result above it |
|---|---|---|
| Node.js 24.21.0, default | 16,333 bytes | 431 |
http.createServer({ maxHeaderSize: 32768 }) | 32,500 bytes passed | 431 at 32,800 |
node --max-http-header-size=32768 | 32,500 bytes passed | 431 at 32,800 |
The 16,333 is not arbitrary. curl also sent Host: localhost:8961, User-Agent: curl/8.14.1 and Accept: */*. Adding up only the header names and values (no colons, spaces or line breaks): 4+14 + 10+13 + 6+3 + 1+16,333 = 16,384 bytes exactly. One more byte and Node answers 431.
2. What curl shows
$ curl -si -H "X: $(head -c 17000 /dev/zero | tr '\0' a)" http://localhost:8961/
HTTP/1.1 431 Request Header Fields Too Large
Connection: close
No body, and your request handler never runs, so nothing appears in your app's logs: Node's HTTP parser rejects the request before your code is called.
3. The localhost cookie trap (reproduced in Chrome)
Cookies are scoped to a host name, not a port. In Chromium 153 we opened http://localhost:8962/ and set five cookies of 4,000 bytes each with document.cookie (20,033 bytes in the Cookie header). Then:
| Next page loaded | Result |
|---|---|
http://localhost:8961/ (another app, default Node limit) | 431, blank white page (<body></body>) |
http://localhost:8962/ (maxHeaderSize 32768) | 200; the server received all 20,033 cookie bytes |
http://127.0.0.1:8961/ | 200: different host name, so no cookies |
http://localhost:8961/ after clearing cookies | 200 |
The cookies set by the app on port 8962 were sent to the app on port 8961 and broke it. That is the classic "431 on localhost in Chrome" report: sessions, analytics and feature flags from every project you ever ran on localhost:3000, :5173 or :8080 share one cookie jar.
4. Fixes, quickest first
- Clear cookies for localhost: DevTools, Application, Storage, Cookies,
http://localhost, Clear all. Opening the app in a private window confirms that cookies are the cause. - Use a different host name per project, such as
127.0.0.1, so cookie jars stop overlapping. - Raise the limit if large headers are legitimate:
node --max-http-header-size=32768 server.js,NODE_OPTIONS=--max-http-header-size=32768for dev servers started by a CLI, orhttp.createServer({ maxHeaderSize: 32768 }, handler). - Shrink the headers: do not store a whole session or a large JWT in a cookie (inspect one with the JWT decoder), and set cookies on the narrowest path and domain.
Behind nginx the same problem shows as 400 Bad Request: Request Header Or Cookie Too Large instead; see Request Header Or Cookie Too Large in nginx. Limits for both servers side by side are in HTTP header size limits, measured.
Frequently asked questions
What causes 431 Request Header Fields Too Large?
The request headers exceed the server's limit. In Node.js 24 the default limit is 16,384 bytes of header names plus values; most often oversized or accumulated cookies push a request over it.
Why do I get 431 on localhost?
Cookies ignore ports, so cookies set by any app on localhost are sent to every other localhost app. In Chromium 153, five 4,000-byte cookies set on localhost:8962 made a Node app on localhost:8961 return 431.
How do I fix 431 in Chrome?
Clear the cookies for localhost (DevTools, Application, Cookies) or try a private window. Loading the same app via 127.0.0.1 returned 200 in our test because it is a different host name.
How do I increase the header size limit in Node.js?
Start Node with --max-http-header-size=32768 (or set it in NODE_OPTIONS), or pass { maxHeaderSize: 32768 } to http.createServer. Both let a 32,500-byte header through in our test.
What is the default max header size in Node.js?
16 KB. With curl's three default headers, the largest extra header value Node.js 24.21.0 accepted was 16,333 bytes, which brings names plus values to exactly 16,384 bytes.
Written with AI assistance. Measured on 2026-10-01 with Node.js 24.21.0 (plain http.createServer on localhost:8961-8963), curl 8.14.1 and headless Chromium 153.0.8010.12 (Playwright, fresh context). We grew one request header to find the exact cutoff, then set five 4,000-byte cookies on localhost from one port and loaded a server on another port. PlainHeaders is our extension; Node.js, curl and Chromium are free.