Nginx and Weird “400 Bad Request” Responses

Most of the LAMP clusters I deal with on a daily basis use the same basic stack – an nginx at the front as a load balancer proxy, apache as the application server (running php), and mysql as the backend. I just realized that this stack might as well be called LNAMP or LAMPN, since nginx plays a big part in it.

Problem with LAMPN, is that it sometimes takes its new stack name seriously, and starts limpin’. Nginx is an excellent front end – it’s highly configurable and highly efficient. But, it has a nasty habit of not letting your requests go through to the application servers if the request is hard for it to understand. Instead, it returns a “400 Bad Request” and dies.

So what was a request that was “hard to understand” in my case? It was a request with a very large “Cookie” header. If the cookies size of a certain domain sum up to more than large_client_header_buffers, your request is simply rejected by nginx. The default for large_client_header_buffers is:

large_client_header_buffers 4 4k 
/* 4k being the page size of the system, can be any size depending on OS */

The cookie header sent from my browser to the domain I tried to access was 4.4k in size, larger than the default size, so nginx flipped. I read it is only a Firefox issue (does IE split the Cookie to chunks? Is it even possible to send multiple chunks of a Cookie header?), but it might as well happen with other browsers and different requests. To solve the problem, the following setting in the http context will solve your problem:

large_client_header_buffers 4 8k

Actually, nginx documentation mentions this problem, but it’s one of those default settings you think to yourself you’ll never have to change. Well, apparently, sometimes you do.

Nginx and Weird "400 Bad Request" Responses

Most of the LAMP clusters I deal with on a daily basis use the same basic stack – an nginx at the front as a load balancer proxy, apache as the application server (running php), and mysql as the backend. I just realized that this stack might as well be called LNAMP or LAMPN, since nginx plays a big part in it.

Problem with LAMPN, is that it sometimes takes its new stack name seriously, and starts limpin’. Nginx is an excellent front end – it’s highly configurable and highly efficient. But, it has a nasty habit of not letting your requests go through to the application servers if the request is hard for it to understand. Instead, it returns a “400 Bad Request” and dies.

So what was a request that was “hard to understand” in my case? It was a request with a very large “Cookie” header. If the cookies size of a certain domain sum up to more than large_client_header_buffers, your request is simply rejected by nginx. The default for large_client_header_buffers is:

large_client_header_buffers 4 4k
/* 4k being the page size of the system, can be any size depending on OS */

The cookie header sent from my browser to the domain I tried to access was 4.4k in size, larger than the default size, so nginx flipped. I read it is only a Firefox issue (does IE split the Cookie to chunks? Is it even possible to send multiple chunks of a Cookie header?), but it might as well happen with other browsers and different requests. To solve the problem, the following setting in the http context will solve your problem:

large_client_header_buffers 4 8k

Actually, nginx documentation mentions this problem, but it’s one of those default settings you think to yourself you’ll never have to change. Well, apparently, sometimes you do.