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 typically responds with a 400 Bad Request error. For oversized request lines, it returns a 414 Request-URI Too Large error. To accommodate larger headers, you’ll need to adjust a few directives. The main directive to focus on is large_client_header_buffers:

large_client_header_buffers 4 16k;

This sets up 4 buffers of 16 kilobytes each. Nginx uses these for reading large client request headers. If a single header doesn’t fit in one of these buffers, you’ll get that 400 error. For smaller headers, Nginx first tries to use the buffer defined by client_header_buffer_size:

client_header_buffer_size 2k;

If a request doesn’t fit this initial buffer, Nginx moves up to the larger ones we just configured.

In older versions of Nginx, there was a separate http2_max_field_size directive for HTTP/2 connections. However, this is obsolete since version 1.19.7. Now, large_client_header_buffers handles both HTTP/1.x and HTTP/2 connections.

Proceed with caution when increasing these values, as setting them too high can leave your server vulnerable to DoS attacks.

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 16384

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 back then, 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