431 Request Header Fields Too Large

The HTTP 431 status code indicates that a server refuses to process a request because HTTP headers are too large.

While the HTTP spec doesn’t impose any limits on the size of headers, most web servers do. Servers can use this status code when the size of a single header field or the total size of all headers exceeds the limit.

More often than not, the culprit is a cookie-related header (Set-Cookie or Cookie). It is also worth checking the Referer and User-Agent headers as they can be easily spoofed.

HTTP/2

According to the HTTP/2 specification, the cookie header may be split into multiple header fields for better compression efficiency (HPACK). That might cause a problem when there are too many cookie-related header fields.

While you can configure some web servers to accommodate larger cookies, keep in mind that this could open an avenue for a denial of service (DoS) attack.

Make sure to clear cookies from your browser before tweaking the configuration parameters.

Nginx

Instead of returning the 431 status code when the cookie or header size is too large, Nginx responds with the 400 Bad Request Request Header Or Cookie Too Large. To accommodate larger cookies or headers, keep increasing the client_header_buffer_size directive until you get a 200 OK response:

client_header_buffer_size 128k;

If you’re using the HTTP/2 module for nginx, you can configure the http2_max_header_size to control the allowed size of all headers. The default is 16K, which means all headers can occupy no more than 16 kilobytes of space after decompression.

Also, consider increasing the limit for the maximum size of a request header field (HPACK-compressed). The default is 4k, which means a request header’s name or value can’t exceed 4 kilobytes.

http2_max_header_size 32k;
http2_max_field_size 8k;

Nginx will disconnect the HTTP/2 session upon encountering large headers or request lines instead of returning 431 or 414 status codes.

Apache

Apache limits the length of HTTP headers to 8,190 bytes (8 kilobytes). You can change this default by specifying the LimitRequestFieldSize directive:

LimitRequestFieldSize 16382

If that doesn’t resolve the 431 errors, consider modifying the LimitRequestLine directive as well; this governs the maximum size of the HTTP request line.

Keep in mind that these directives must be defined before loading virtual hosts, which means they should be placed at the top of your config file.

Node.js

In Node.js, the default limit for header size was reduced from about 80 kilobytes to 8 kilobytes to prevent denial of service attacks using large HTTP headers (CVE-2018-12121). However, since this configuration was immutable at the time, the change broke many applications, necessitating an increase to 16 kilobytes in later versions.

Starting from versions 10.15.0 and 11.6.0, you can pass the --max-http-header-size flag to control the maximum header size.

node --max-http-header-size=65536 index.js

Alternatively, you could pass the maxHeaderSize option for servers and client requests.

See also