This article describes the troubleshooting steps to identify the cause of various HTTP 400 errors when using IIS.
Overview
After an HTTP client (such as Microsoft Edge) sends an HTTP request to an IIS server, it might display the following type of error message:
HTTP 400 - Bad Request
In this scenario, IIS rejects the client's HTTP request because the request doesn't meet the server's HTTP parsing rules, exceeds time limits, or fails some other rules that IIS or HTTP.sys requires incoming requests to adhere to. IIS sends the HTTP 400 - Bad Request status back to the client, and then terminates the TCP connection.
When troubleshooting an HTTP 400 condition, it's important to remember that the underlying problem is that the client has sent a request to IIS that breaks one or more rules that HTTP.sys is enforcing. With that in mind, you'll want to see what exactly the client is sending to IIS. To do it, capture a network trace of the client sending the bad request. You can analyze the trace to see the raw data that the client sends to IIS, and to see the raw response data that IIS sends back to the client. You can also use an HTTP sniffer tool called Fiddler, a great tool as it allows you to see the HTTP headers even if the client and server are communicating over SSL.
The next data item you use is the C:\Windows\System32\LogFiles\HTTPERR\httperr.log file. In IIS, the HTTP.sys component handles incoming HTTP requests before they're passed along to IIS and is responsible for blocking requests that don't meet the IIS requirements. When HTTP.sys blocks the request, it logs information to its httperr.log file concerning the bad request and why it was blocked.
Märkus
For more information on the HTTP API error logging that HTTP.sys provides, see Error logging in HTTP API.
It's technically possible, although not very likely, that a client might receive an HTTP 400 response, which doesn't have an associated log entry in the httperr.log file. It could happen if an ISAPI filter or extension, or an HTTP module in IIS, sets the 400 status, in which case you could look at the IIS log for more information. It could also happen if an entity between the client and the server, such as a proxy server or other network device, intercepts a response from IIS and overrides it with its own 400 status and/or "Bad Request" error.
Märkus
This article mainly discusses the common HTTP 400 errors before reaching your website. In some scenarios, your website might also return HTTP 400 errors to clients due to custom code logic or runtime (such as ASP.NET) configuration. If you still can't resolve the HTTP 400 errors after performing the steps in the following sections, try to troubleshoot using the Failed Requests Tracing feature in IIS. If you find the HTTP 400 errors are actually set by your website's corresponding runtime handler, such as ASP.NET, you might need to inspect the details of the requests and responses, along with your website's related code logic and runtime configuration, to understand the cause of the HTTP 400 errors.
Sample scenario
Following is an example of an HTTP 400 scenario, where a client sends a bad request to IIS and the server sends back an "HTTP 400 - Bad Request" message.
When the client sends its request, the browser error it gets back looks like:
Bad Request (Header Field Too Long)
Capturing a network trace of the request and response, you see the following outputs:
REQUEST:
Output
HTTP: GET Request from Client
HTTP: Request Method =GET
HTTP: Uniform Resource Identifier =/1234567890123456789012345678901234567890/time.asp
HTTP: Protocol Version =HTTP/1.1
HTTP: Accept-Language =en-us
HTTP: UA-cpu =x86
HTTP: Accept-Encoding =gzip, deflate
HTTP: Host =iisserver
HTTP: Connection =Keep-Alive
HTTP: Data: Number of data bytes remaining = 14 (0x000E)
RESPONSE:
Output
HTTP: Response to Client; HTTP/1.1; Status Code = 400 - Bad Request
HTTP: Protocol Version =HTTP/1.1
HTTP: Status Code = Bad Request
HTTP: Reason =Bad Request
HTTP: Content-Type =text/html
HTTP: Date =Wed, 14 Nov 2012 20:36:36 GMT
HTTP: Connection =close
HTTP: Content-Length =44
HTTP: Data: Number of data bytes remaining = 63 (0x003F)
You notice that the response headers don't tell as much as the error message in the browser. However, if you look at the raw data in the response body, you see more:
You can see that the error message text displayed in the browser is also viewable in the raw response data in the network trace.
The next step is to look at the httperr.log file in the C:\Windows\System32\LogFiles\HTTPERR directory for the entry that corresponds to the bad request:
Output
#Software: Microsoft HTTP API 1.0
#Version: 1.0
#Date: 2012-11-14 20:35:02
#Fields: date time cs-version cs-method cs-uri sc-status s-reason
2012-11-14 20:36:36 HTTP/1.1 GET /1234567890/time.asp 400 FieldLength
In this scenario, the Reason field in the httperr.log file provides the exact information you need to diagnose the problem. You see that HTTP.sys logged FieldLength as the reason phrase for this request's failure. Once you know the reason phrase, check the table in Kinds of errors that the HTTP API logs section to get its description:
FieldLength: A field length limit was exceeded.
So at this point you know from the browser error message and the HTTP API error logging that the request contained data in one of its HTTP headers that exceeded the allowable length limits. For this example, the HTTP: Uniform Resource Identifier header is purposefully long: /1234567890123456789012345678901234567890/time.asp.
Since you know the reason phrase and error are suggesting a header field length exceeding limits, you can narrow our search in the Registry Keys table as such. The prime candidate here is:
Registry key
Default value
Valid value range
Registry key function
WARNING code
MaxFieldLength
16384
64 - 65534 (64k - 2) bytes
Sets an upper limit for each header. See MaxRequestBytes. This limit translates to approximately 32k characters for a URL.
1
To reproduce this error for this example, the MaxFieldLength registry key was set with a value of 2. Since the requested URL had a HTTP: Uniform Resource Identifier header field with more than two characters, the request was blocked with the FieldLength reason phrase.
Another common HTTP 400 scenario is one where the user making the HTTP request is a member of a large number of Active Directory groups, and the website is configured to user Kerberos authentication. When this scenario occurs, an error message similar to the following one will be displayed to the user:
Bad Request (Request Header Too Long)
In this scenario, the authentication token that is included as part of the client's HTTP request is too large and exceeds size limits that http.sys is enforcing. This problem is discussed in detail, along with the solution, in HTTP 400 - Bad Request (Request Header too long) responses to HTTP requests.
Overview The <serverRuntime> element configures the following settings that are related to the Internet Information Services (IIS) 7 server runtime: Se...
Every Web-Site Administrator or Web Developer has seen '404 - File not found', '401 - Unauthorized' or '500 - Server Error' messages in his browser. This ar...