Unable to validate data. at System.Web.Configuration.MachineKeySection.GetDecodedData - asp.net

I have several websites which get approximately 3000 pageviews in total per day, and I get this viewstate error roughly 5-10 times per day, caught in global.asax:
System.Web.HttpException: Unable to validate data. at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
I have tried:
hard-coding the machine key in web.config for all websites
hard-coding the machien key in machine.config
adding items to the pages section of the web.config for all websites.
Machine key looks like:
<machineKey validationKey="key goes here" decryptionKey="key goes here" validation="SHA1" decryption="AES" />
Pages section looks like:
<pages renderAllHiddenFieldsAtTopOfForm="true" validateRequest="false" enableEventValidation="false" viewStateEncryptionMode="Never">
The errors are not related to application pool recycling as best I can tell, as the pool is set to recycle at every 100,000 requests. I am not running a web farm or web garden. Quite often I get two or three of these errors in a row, as if a user is getting an error, going back, and then clicking the link again.
Anyone have any ideas?

I have seen "random" ViewState errors before caused by slow internet connections. The slow connections would cause the page to be visibly rendered to the user, however it hadn't completely loaded. The user would then take action on the form and thus "random" issues would occur.
See if you can correlate the exception timestamps to specific pages being requested in the IIS logs. You could then try to re-create the low bandwidth scenario with something like Firefox Throttle.
Similar question below confirms my experiences and probably what your are seeing as well:
ASP.NET: Unable to validate data

Related

Intermittent ASP.net IIS8.5 uncatchable 500 internal-server-error on Azure cloud service

Lets start with a little background information. I am running a very simple ASP.net MVC Azure cloud service (a web role, Windows Server 2012 R2 with IIS 8.5). This service receives statistics from a flash client, which posts data roughly every 10 seconds (for potentially very large number of clients) and JavaScript. All the service contains is a single controller with two simple actions with a bunch of parameters (representing the individual statistics which are send in various combinations). All the service does is set the CORS and cookie responses (the clients/JavaScript can be embedded on random domains), verify the integrity of the received data and then store it into an Azure table storage account.
In order to ensure our service operates optimally we use New Relic to track service performance, and in order to ensure that our data is accurate (i.e. we successfully record all received messages) we implemented a custom error handling solution so we can fix any problems/bugs that might arise.
We have load tested our service using jmeter and encountered no problems, but now that we have deployed to a live environment and our service is being used we are starting to encounter occasional 500 internal server errors (approx 5% of requests). The big problem being that our own error handling code is not detecting these errors, however New Relic does report certain requests generating a 500 internal server error (with no further information like a stack trace, sometimes with, sometimes without reported parameters).
Our custom error handling consists of an HTTP module which registers to both the AppDomain.CurrentDomain.UnhandledException and the context.Error events. In theory this should be catching (and then logging) any exceptions which are not already being caught (and logged) inside our own code. Relevant web.config sections are configured in the following manner:
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
<error statusCode="404" redirect="~/404.aspx" />
<error statusCode="500" redirect="~/500.aspx" />
</customErrors>
and
<httpErrors existingResponse="Replace">
<clear />
<error statusCode="404" path="404.html" responseMode="File" />
<error statusCode="500" path="500.html" responseMode="File" />
</httpErrors>
<modules>
<add type="namespace.UnhandledExceptionModule" name="UnhandledExceptionModule" preCondition="managedHandler" />
</modules>
However, this is not the case. I have tried turning on all kinds of logging but the IIS logs are useless (they only show that a 500 response was returned, but no other useful information). The only useful information I have been able to gather is from the failed request traces, but I have not been able to determine what the actual problem is from that information (googling the error code or exception leads to nothing concrete). A screenshot of the relevant section of a failed trace can be found here:
http://i57.tinypic.com/20acrip.jpg
I also uploaded the complete trace here:
http://pastebin.com/fDt3thvr
Each failed request generates exactly the same log, so the errors we are seeing are consistently being caused by the same problem. However, I am not able to determine what this problem is, let alone find a way of fixing it. Even though I have an error code and message, googling them only returns very old topics on issues that have been fixed 6 years ago.
It is pretty important for our business that these messages can be recorded with a high degree of accuracy, but as it stands now I have no further ideas on how to gain better information on what is happening on these servers. We are also not able to replicate this behavior in a controlled environment.
Also, our error logging itself does work properly. 'Normal' errors are logged as expected and we have also verified the HTTP module actually works.
Edit:
The controller pseudo code is as follows:
[HttpPost]
public ActionResult Method(...)
{
// Set cookie and CORS reponse, check for early out.
if(earlyOut)
return 404;
// Store received values.
azuretable.ExecuteAsync(TableOperation.InsertOrMerge(...));
return 200;
}
Edit2:
I have spend some time analyzing failed request traces and they mostly seem to be generated by users with IE9. I actually managed to reproduce the error 2 times by quickly leaving the page while it is loading, as the problem seems to be caused by aborted Ajax calls (which we make the most of during page load). Why would an aborted call cause a 500 error though instead of being handled neatly?
Do the cookies exceed 4k ? The same thing happened to us on IIS, and the requests sometimes ended up with 500 Internal Server error. The errors were virtually untraceable.
I reproduced the issue by simply inflating a cookie over the 4093 bytes limit.
I think that it is because you are not awaiting your async method call, or your are not returning an awaitable response. I had exactly this issue when I forgot to do that.
await azuretable.ExecuteAsync(TableOperation.InsertOrMerge(...))
Then you should be good. I think you'll find that the async call is finishing after your call has completed back to the caller.

Viewstate Validation fails in web-farm - Usual suspects eliminated

I think that I've tried all of the standard responses to this problem, and I know that I've read hundreds of questions and posts about this problem, but none of them seem to have resolved it or shed any light on what the cause is in my scenario. (I'm 5 hours down and no nearer :-( )
I have a web-farm of 2 servers.
I have set the machine key and validation key in machine.config on both machines
Encryption: SHA1, Decryption: AES - These are the defaults, could it help to change them?
I have verified that no other config files in the chain (web.cfg, apphost etc.) have a setting for these values.
I have added a page to the site (based on this SO) that spits the machine key values back out, and verified that they are the same across requests to both machines and match the values that are in machine .config
The server side session state is in a shared state-server, I have verified that sessionid remains constant between requests to the 2 servers.
I have verified that the page is completely loaded and the __EVENTVALIDATION hidden field has been rendered into the page before initiating the post. The viewstate size is not too bad at 7.64kb
When a page is rendered from a request to server 1 and then posted back to server 2, I get the dreaded...
Error Message:
Unable to validate data.
at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) HttpApplication.RecordError => HttpApplication.RaiseOnError => global_asax.Application_Error
The post is triggered by a standard, unadulterated asp linkbutton, there is no ajax going on on the page.
Any and all help will be greatly appreciated.
Setting enableViewStateMAC = false is not a solution :-)
Having inherited the servers in the state that they were configured, I never questioned the validity of the keys!!! ...Just checked that they matched on both servers...
Leaving all the encryption / decryption and validation algorithm settings as they were, I generated new keys using this tool which has a few more options than the others.
Problem solved
Moral of the story: If in doubt, generate new keys
... but why and how? Some postbacks with viewstate were working just fine with the old keys, it was only when the postback was to a different server that the problem became evident. If the keys were invalid - missing a character or something - then every postback should have failed - I think
If you've established that the machine keys are the same on both boxes, could it be the encryption/decryption thereof ?
Have you tried using Triple DES and setting the decryptionKey in the machine.config on both servers?
Check here
Also a easy way of making sure the machineKeys are the same is to add a line like this in the web.config.
NB: Assuming you have the same web.config on both servers and making sure that the validationKey and decryptionKey is valid
You can use http://aspnetresources.com/tools/machineKey to generate it.
<system.web>
<machineKey validationKey="*D9B0EDEA69D81A89BF5FBA2B08BAF691013F86B89A1F6BA8068C6ECC9539074" decryptionKey="*AE2B1966AF65D08F03EDFB" validation="SHA1" decryption="AES" />

This is an invalid script resource request. ~/scriptresource.axd

Error at System.Web.Handlers.ScriptResourceHandler.ProcessRequest(HttpContext
context) at System.Web.HttpApplication.CallHandlerExecutionStep.
System.Web.HttpApplication.IExecutionStep.Execute() at
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously)
I am getting the above error from a production server.
We have six production servers and we get the above error from three production servers only.
Remaining three are working fine.
We have following setting for machinKey in all six servers. Path :
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config.comments
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config.comments
OLD Setting:
< machineKey validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"
validation="SHA1"
decryption="Auto"
compatibilityMode="Framework20SP1" / >
CHANGED TO SPECIFIC KEY
< machineKey validationKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
decryptionKey="XXXXXXXXXXXXXXXXXXXXXXXX"
validation="SHA1"
decryption="AES"
compatibilityMode="Framework20SP1" />
but getting same exception.
Can any one please tell me what could be the exact problem?
This can be caused by search engines crawling through your pages. Sometimes they hit the ScriptResource.axd file and generate the error you are seeing.
If you can log the IPs that are causing this error, look them up and see where/who they are.
Of course, if you are only getting this from 3 of 6 servers in your web farm, something else could be wrong.

Strange exception when using Async in .net application

I created an asp.net application that asks users to add titles to a set of videos on a web page, and after it's submitted, begins writing manifest files and uploading the videos on a separate thread, using .net async. Most of the time it works well, however every once in a while I get the following exception:
System.Threading.ThreadAbortException: Thread was being aborted.
at System.Net.UnsafeNclNativeMethods.OSSOCK.send(IntPtr socketHandle, Byte* pinnedBuffer, Int32 len, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, SocketError& errorCode)
If anyone can let me know what this exception means, and what could be triggering it.
This is usually a timeout error.
Have you set a timeout or MaxLength for the file being uploaded? It could be exceeding the default values.
You can set them in your web.config
<system.web>
<httpRuntime executionTimeout="9999999" maxRequestLength="2048000" />
</system.web>
Is it possible that your background thread is trying to write to the network after the initial web page request has completed? If so, the net connection will be gone, and you'll get an Exception.

Why might my users be being logged out after a minute or so?

I have a Asp Mvc 2 site using forms authentication. When I run it locally I can log in and stay logged in indefinitely.
However when I put it on the server I seem to only stay logged in for a few minutes and then seems to be logged out. I have looked at the cookies and there are 2 which seem relevant:
.ASPXAUTH which is a session cookie
.ASPXANONYMOUS which expires in 3 months.
When I refresh the page the cookies stay the same until I get logged out, when I seem to get a new .ASPXANONYMOUS cookie, but the .ASPXAUTH seems to be the same.
It seems that I might be able to stay logged in until I do something after a certain amount of time. If I submit a form as soon as I am logged in then it works ok, but if I keep submitting data again and again then after a minute or so, one of the submits will happen as a logged out user and not as the user who was logged in, which all the other submits worked as.
What might cause this behaviour and how can I track down what is different & change it so that I can stay logged in indefinitely?
EDIT,
its a single server, but after some more investigation and searching the likely candidate seems to be that I am using more than 100mb on the server and the application pool is getting recycled. I suppose now i need to know
How can I check how much memory I'm using.
What advice there is to reduce that.
Could it be that the ASP.NET application is being re-cycled or shutdown (e.g. due to idle timeout, or newly built/changed assemblies)?
When an ASP.NET web application starts up it will, by default, generate encryption keys for view state and session cookies. This will invalidate any such data originally served from an earlier run of the application (or from a different system).
To have sessions survive ASP.NET application cycles (and multi-server farms) you can specify the keys in your web.config:
<system.web>
...
<machineKey
decryption="AES"
validation="SHA1"
decryptionKey="..."
validationKey="..."
/>
where decryptionKey and validationKey are hex strings of length depending on the algorithm (with AES: 64 digits and SHA1: 128, for other algorithms check MSDN).
These keys should be cryptographically generated, and .NET has the types to do this which can be used from PowerShell:
$rng = New-Object "System.Security.Cryptography.RNGCryptoServiceProvider"
$bytes = [Array]::CreateInstance([byte], 16)
$rng.GetBytes($bytes)
$bytes | ForEach-Object -begin { $s = "" } -process { $s = $s + ("{0:X2}" -f $_) } -end { $s}
For AES use the above array length, for SHA1 use a length of 64.
It is quite likely that Session Timeout on the web server is configured to a much smaller timespan than you have set in your Form Authentication configuration in web.config.
The default Session Timeout is 20 minutes for IIS6 and IIS7.
If you have access to the web server's admin interface, you can raise the timeout via the GUI, but it can also be set from the config file if your IIS7 using the <sessionState> and <sessionPageState> sections:
http://msdn.microsoft.com/en-us/library/cc725820(v=ws.10).aspx
Check the webconfig authentication section
<authentication mode="Forms">
<forms name="UniqueName" loginUrl="login.aspx" path="/" >
</forms>
</authentication>
Ensure that the authentication cookie name for each hosted site is unique.
Came here with a similar issue, following the suggestion by #Richard, I looked at the Application Pools' recycling settings. What I found was the settings were changed and the Regular time intervals (in minutes) value was set to 1 minute. This meant that the app pool was being recycled each minute.
To change that, Right-click on the application pool, select the Recycling option, change the value under Regular time intervals (in minutes). I set it to the same value as the other Application Pools were using.
This change fixed the issue, turns out it was set to a low value a while back while during some misguided troubleshooting with an expired SSL certificate.
If none of these work, check in the Application Pools and ensure that the Idle Timeout is set to 20+ minutes. Click on the application pool, select the Advanced Settings link to the right, find the Process Model section, and increase the Idle Timeout value there.

Resources