Reputation: 61
We are doing a load/performance test on our Azure cloud service, where we hosted Web APIs. After a certain number of calls (say 500), cloud service is giving bad request error.
We have built web APIs in c# using web role and hosted them in Azure cloud service. I went through a few articles/forums and tried a couple of options as mentioned below: 1. Tried increasing cloud service VM instance size. 2. Tried increasing 'maxAllowedContentLength' value to 52428800. 3. Tried increasing 'maxRequestLength' value from 5120 to 16240. 4. Used VS Diagnostic tool to check if the issue is because of memory leak. None of them worked.
After hitting endpoint for around 450 - 500 times, this error comes only comes from the endpoints which involve communication to subsystems. This error is not reproducible locally. To come out of this problem, either we have to redeploy the cloud service or restart the cloud service. Ideally, cloud service should work until it's resource consumption reaches 100%. But getting below error after every approx 500 calls with max 10 - 15% resource utilization.
<HTML>
<HEAD>
<TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii">
</HEAD>
<BODY>
<h2>Bad Request - Request Too Long</h2>
<hr><p>HTTP Error 400. The size of the request headers is too long.</p>
</BODY>
</HTML>
Upvotes: 5
Views: 42221
Reputation: 962
I found the answer on StackOverflow:
Check the MSDN:
Cause
This issue may occur when the user is a member of many Active Directory user groups. When a user is a member of a large number of active directory groups the Kerberos authentication token for the user increases in size. The HTTP request that the user sends to the IIS server contains the Kerberos token in the WWW-Authenticate header, and the header size increases as the number of groups goes up. If the HTTP header or packet size increases past the limits configured in IIS, IIS may reject the request and send this error as the response.
Resolution
To work around this problem, choose one of the following options:
A) Decrease the number of Active Directory groups that the user is a member of.
OR
B) Modify the MaxFieldLength and the MaxRequestBytes registry settings on the IIS server so the user's request headers are not considered too long. To determine the appropriate settings for the MaxFieldLength and the MaxRequestBytes registry entries, use the following calculations:
Calculate the size of the user's Kerberos token using the formula described in the following article:
New resolution for problems with Kerberos authentication when users belong to many groups http://support.microsoft.com/kb/327825
Configure the MaxFieldLength and the MaxRequestBytes registry keys on the IIS server with a value of 4/3 * T, where T is the user's token size, in bytes. HTTP encodes the Kerberos token using base64 encoding and therefore replaces every 3 bytes in the token with 4 base64 encoded bytes. Changes that are made to the registry will not take effect until you restart the HTTP service. Additionally, you may have to restart any related IIS services.
...
If MaxFieldLength is set to its maximum value of 64 KB, the MaxTokenSize registry value should be set to 3/4 * 64 = 48 KB.
Upvotes: 1
Reputation: 1093
My problem was:
We have a special user with some roles, more than 65 roles. This issue causes the huge size of request header. because header contains user claims.
Change the roles and claims solved the problem.
Upvotes: 0
Reputation: 1264
For Me I Spent days looking into the issue. Reading blobs and solutions, cleared cache, set max limit of header size to a bigger number, nothing worked. Eventually it would fail.
This issue did not occur if i redploy my application but over a period of time this would start coming up,which made me realize it might be adding in memory.
I was calling another API from my project where we created the request and sent it and got the data.
public async Task<DataList> GeDataList()
{
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await _tokenProvider.GetBearerToken());
Client.DefaultRequestHeaders.Add("X-CorrelationId", Guid.NewGuid().ToString());
var requestMessage = new HttpRequestMessage()
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{Config.apiurl}{string.Format(Config.id, id2 == null ? id1 : id2)}")
};
requestMessage.Headers.Add(Constants.TRACE_HEADER, "true");
requestMessage.Headers.Add(Constants.SUBSCRIPTION_KEY_HEADER, Config.APIKey);
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestdata), null, "application/json");
...................................
...................................
...................................
}
Now this was the culprit Key
Client.DefaultRequestHeaders.Add("X-CorrelationId", Guid.NewGuid().ToString());
Without even seeing it, this Client was a class Level variable of HttpClient. Creating a single instance of HttpClient is okay, but you have to realize that
.Add Header method, always appends to a key and does not override. Many people assume it to be key value.It is actually key and aaray of values. So each requests keeps on adding the correlation Id a s new object to the array. And eventually this becomes a large amount of header
Fix: You can clear the key first
if(Client.DefaultRequestHeaders.Contains("X-CorrelationId")) {
Client.DefaultRequestHeaders.Remove("X-CorrelationId");
}
Client.DefaultRequestHeaders.Add("X-CorrelationId", Guid.NewGuid().ToString());
You would still need to handle the conquerency issues because multiple conquerent request might update and override your headers.
Upvotes: 13
Reputation: 5294
It’s not so easy to answer the question 'what’s gone wrong here?' when you’re presented with a 400 error. It means that the request itself has somehow become defective. The internet protocol HTTP hasn’t been correctly adhered to (at least according to the webserver), which is why the request cannot be processed. The server has interpreted the request as faulty or even harmful. Therefore, it prevents the website from being properly displayed. The reasons for the error report are usually related to the browser used or a user error.
Incorrect URL: Just like the 404 error, a bad request is generated if users enter the internet address incorrectly or, for example, insert special characters that aren’t allowed.
Incorrect cookies: If the cookies in your browser are outdated or incorrect, this is another reason that an error 400 might occur. Outdated DNS records: Your DNS cache might contain data that links to incorrect IP addresses.
Files too large: If you try to upload particularly large files, the server can refuse to accept them. The server classifies this as a ‘Bad Request’. Header too long: When communicating, the client and server use the header to define the request. Some webservers set an upper limit for the length of headers. It’s not immediately obvious what the communication problem is when you’re presented with the error message 'HTTP 400 Bad Request'. However, if the target webserver uses IIS 7.0, IIS 7.5, or IIS 8.0, more detailed information can be obtained from the status code:
Error can be cause from any of the above reason. Hope it helps.
Upvotes: 0