Recently seeing a bunch of 400s

Dave Cheney dave at cheney.net
Tue Dec 16 11:56:37 MSK 2008


Apologies, I stand corrected.

Cheers

Dave

On 16/12/2008, at 7:30 PM, Igor Sysoev wrote:

> On Tue, Dec 16, 2008 at 01:55:53AM -0500, Dave Cheney wrote:
>
>>
>> 499 is nginx's error code for 'client closed connection without  
>> receiving
>> the whole body', that is, they pressed the stop button on their  
>> browser, or
>> navigated away. It's generally harmless
>>
>> If you see this pattern
>>
>> client --> SYN     --> nginx
>> client <-- SYN/ACK <-- nginx
>> client --> SYN/ACK --> nginx
>> client --> FIN     --> nginx
>>
>> then nginx will have accepted the connection and you will get a 400  
>> in the
>> access log
>
> No, according to src/http/ngx_http_request.h:
>
> /*
> * HTTP does not define the code for the case when a client closed
> * the connection while we are processing its request so we introduce
> * own code to log such situation when a client has closed the  
> connection
> * before we even try to send the HTTP header to it
> */
> #define NGX_HTTP_CLIENT_CLOSED_REQUEST     499
>
> So, the above pattern will result in 400, if nginx has catched to  
> accept()
> before FIN has been received or in this error: "accept() failed (53:  
> Software
> caused connection abort) while accepting new connection on  
> 0.0.0.0:80",
> if nginx has called accept after FIN has been received.
>
> 499 means that nginx has got a whole request, but did not send  
> anything
> to client.
>
>> however this
>>
>> client --> SYN     --> nginx
>> client <-- SYN/ACK --> nginx
>> client --> RST     --> nginx
>>
>> is not a complete TCP connection, and nginx will not return from  
>> accept().
>>
>> <speculation>
>> Browsers open several TCP connections to request resources from a  
>> page, it
>> could be that the browser is proactively opening secondary  
>> connections as
>> it sends the intial request. This request is returned with a 400  
>> error code
>> because of the cookie error, and so the browser closes any  
>> outstanding
>> secondary TCP connections.
>> </speculation>
>>
>> Cheers
>>
>> Dave
>>
>>
>> On Mon, 15 Dec 2008 18:06:06 -0800, Neil Sheth <nsheth at gmail.com>  
>> wrote:
>>> I'm not fully knowledgeable about the network layer, so my  
>>> explanation
>>> may have been incorrect.  I asked our hosting provider to look at  
>>> it,
>>> thinking it could be something they could help with, this was their
>>> response:
>>>
>>> ---------------------------------------
>>> From looking over packet dumps I have collected, this appears to  
>>> be a
>>> client-side issue and not something caused by the server.
>>>
>>> The requests resulting in 400 error codes appear to correspond to  
>>> the
>>> client opening and then closing the connection. In the packet  
>>> dump, I
>>> see the clients initiate the connection with a SYN and then  
>>> immediate
>>> close it with FIN, ACK or RST, ACK. Similar behavior exists for 499
>>> errors except the client sends a HTTP request before closing the
>>> connection.
>>>
>>> The clients appear to be aborting the connection and then  
>>> momentarily
>>> later retrying it. Maybe they think the page isn't loading and retry
>>> it.
>>> --------------------------------------------
>>>
>>>
>>> I see another ongoing thread about 400s with firefox, perhaps I'm
>>> experiencing the same issue.
>>>
>>>
>>> On Thu, Dec 11, 2008 at 7:17 PM, Dave Cheney <dave at cheney.net>  
>>> wrote:
>>>>
>>>>> Looking at a tcpdump for a specific case, figuring that  
>>>>> basically a
>>>>> first packet comes, but our server didn't expect it (could be  
>>>>> due to
>>>>> the fact that there was no original handshake to establish the
>>>>> connection or our server closed the connection but the remote  
>>>>> machine
>>>>> didn't get the packet to realize it was closed), that's why our  
>>>>> host
>>>>> replies with RST flag, saying that the packet was unexpected and  
>>>>> that
>>>>> the record of the connection should be closed on the other side.  
>>>>> And
>>>>> it records it with the 400 error in the access file, logging  
>>>>> that some
>>>>> garbage came, and that it correctly reset the connection.
>>>>
>>>> That doesn't make sense. If you send a packet to a port without
>>>> establishing a connection you'll get a RST, but that comes from  
>>>> the tcp
>>>> stack, the application waiting on select() or accept() will be
>> completely
>>>> unaware of the failed connection attempt. Unless, of course,  
>>>> there is a
>>>> bug
>>>> in your OS's TCP stack.
>>>>
>>>> Cheers
>>>>
>>>> Dave
>>>>
>>>>
>
> -- 
> Igor Sysoev
> http://sysoev.ru/en/
>






More information about the nginx mailing list