The mysterious problem with WebResource.axd

UPDATE: Solution to WebResource.axd exception

I have tried to figure out why a customer get a strange error message on their ASP.NET web site that stops the whole site from working until you restart the whole IIS.

The exception “The WebResource.axd handler must be registered in the configuration to process this request” occurred quite randomly at first sight. After some investigations I found that the site usually stopped working if you called some of the pages immediately after a restart of the web application. This happens for example when you change in web.config but an unload of your AppDomain can be triggered by other mechanisms, too.

I found no clues to the cause when I searched on the error message, only a lot of question and other desperate people.

Looking closer at the call stack and browsning around with Roeders Reflector I found that the cause of our problem with WebResource.axd is in the method EnsureHandlerExistenceChecked in the class System.Web.Handlers.AssemblyResourceLoader:

EnsureHandlerExistenceChecked()

As you can see in the code above, if the test fails once it will never re-test since handlerExistenceChecked is true and the site will stop working forever.

This check is called for several reasons. One of them is because components like the RequiredFieldValidator uses the ClientScriptManager to insert links on the page to JavaScript that is embedded inside a resource in an assembly somewhere. To make the resource available from the browser the generated link contains a reference WebResource.axd that is registered as a HttpHandler in machine.config redirecting calls with that filename to the AssemblyResourceLoader class.

The only way to recover from the error I have found is to stop the site, run iisreset /restart and wait for a while before you start the site again.

I have not manage to find the exact reason for why the test fails initially. I have some theories but they are hard to validate since used classes and methods are private or internal. One guess is that FindMapping returns null because the HttpHandler collection has not yet been loaded. Another guess is that HttpHandlerAction has not been correctly initialized so TypeInternal is null. It could even be possible that there is a problem with the type system (because ASP.NET applications unloads the AppDomain, generat assemblies dynamically and loads them, etc) so you actually have two instances of the same underlying system type making the Equal operator give an incorrect result.

It really does not matter why it does not work since we can not patch Microsoft’s framework ourself or wait for a hot fix. If anyone else has some clues or have done some research on this problem, please let me know!

My workaround to recover from the error is to use reflection to clear one of the private static flags so it re-runs the test. (Use of reflection like the requires that your application does not run with a low trust level so it might not work everywhere.) Since it is expensive to use reflection I only run the check in the Error event handler in my Application object.

Source code for workaround

Any feedback is appreciated.

Download example code here.

Bookmark and Share

Tags: , ,

  1. Marnix’s avatar

    Hi Fredrik,

    I have the same issue and I’m able to reproduce it by overwriting an assembly with embedded resources with a newer version. I’m guessing the problem occurs somewhere while reloading the assembly. Normally an update like this will trigger the AppDomain to be reloaded which would confirm your story.

    I’ve tried your code and so far it works like a charm :)

    Thanks,
    Marnix

    Reply

  2. Jimmy’s avatar

    Hi! I have experienced this problem two times this week only, and its very frustrating. But you don’t need to restart the IIS to fix this. Just stop the web, recycle the application pool and start the web again. I will try your fix and hopefully it will work for me too. Thanks. /Jimmy

    Reply

  3. Andreas Ek, Internetfabriken’s avatar

    Hello!
    Could you, please, publish the code as text? It would be a lot easier ;-)

    Reply

  4. Fredrik Haglund’s avatar

    Hej Andreas!

    Download example code here: http://fredrikhaglund.se/blog/070927/Global.asax.zip

    /Fredrik

    Reply

  5. Andreas Engström’s avatar

    Hej Fredrik, vi har också lidit av detta problem (bland andra) finns lite att jobba på i nya releasen innan den är ok.

    Tack för din fix

    MVH
    A Engström /din elev :)

    Reply

  6. Jon’s avatar

    I’m desparate for a solution/workaround and hope to try this next. Have you had any more experience with the overall success/risks of this method?

    Reply

  7. Fredrik Haglund’s avatar

    Jon, it appears to work well for us. The site has not stopped working since we applied the fix.

    We still see the error from time to time after the appdomain reloads so the sollution is not perfrect. But now it does not stop permanently but recovers.

    I did not manage to figure out the root cause of the problem but it appears to affect larger asp.net applications with many assemblies in the bin folder with constant trafic more often. Pages without need for scrips do not get the error (since they do not user the webresource.axd handler) and we have a validation control on our start page so it is quite obvious when it is not working…

    /Fredrik

    Reply

  8. Fredrik Haglund’s avatar

    Note! The fix above applies for IIS6 only.

    There are other issues with IIS7 that you can read about in the forums

    Reply

  9. Martin’s avatar

    To clear things up: this workaround does not fix this problem, it does just allow the handlers to reload if the app pool has already crashed. So if you use this code, you will still get the error, but you do not have to reset the iis every time it happens.

    Reply

  10. Fredrik Haglund’s avatar

    Martin, that is correct. My guess is that this error is triggered by some sort of race condition during startup. This will only allow it to try again… /Fredrik

    Reply

  11. Mats’s avatar

    Hi!
    We have the same problem with some of our EPiServer sites. Thank you for the workaround!
    /Mats

    Reply

  12. Fredrik Haglund’s avatar

    Update: Scott Guthrie help me to get in contact with Steve Molloy and Matt Gibbs at Microsoft about this issue.

    Steve has been running this in the stress lab for a couple days. After several hundered machine-hours of stress while touching config every 3 minutes they have not been able to reproduce the issue.

    This is probably a race condition that occurs because the framwork or application we have does something special. But I have not been able to create a simple reproducable test case. Has anyone?

    I have identified several things that increases the probability to get this issue:
    * You have login controls or other controls that uses validation on your start page. (Validation needs javascript and EnsureHandlerExistenceChecked will called because Webresource.axd is used)
    * You have a lot of assembles in your bin folder.

    In my case, the framwork I use (EPiServer), has code that loads all assemblies in the bin folder in the constructor of the global.asax class. It does this because it looks for classes with plug-in attibute. This in combination with the call to EnsureHandlerExistenceChecked on the start page does probably increase the risk for the problem.

    /Fredrik

    Reply

  13. Jørgen Tonvang’s avatar

    We’ve experiencing ever since we started using EPi 5.
    It occurs very frequently on both production and development servers. We’ve never seen it on independent asp.net 2.0 sites or EPi 4.6.

    We have several developers working against the same dev. server for a new enterprise site, and I’d say that after a compile it has a 50/50 chance of triggering the error.

    All the top google results for this seems to be EPi related, so this is definetly something they should look into.

    /Jørgen

    Reply

  14. Fredrik Haglund’s avatar

    Per Bjurström at EPiServer found the cause of this issue. He has also a workaround that prevents it from happening.

    The code above only recovers the application after the error is detected.

    Reply

  15. Paul McEwan’s avatar

    Fredrik, we’re having this same problem, but the workaround doesn’t seem to help. As soon as we put anything with AutoPostBack=”True” or a validation control it errors. We assume because of client-side Javascript? Do you have any more information from MS on this issue?

    Thanks

    – Paul

    Reply

  16. Calle’s avatar

    Hi!
    Before you all use the fix. Check your IIS-settings:
    Under add “application extension mapping” for wildcard (.*). Make sure that “validate that file exists” is NOT checked.
    I unchecked it and solved the problem for me…

    Reply

  17. Victor’s avatar

    I found that some extensions for the web site were mapped to aspnet 1.1 isapi dll (aspnet_isapi.dll) even though the application is set to run on 2.0 in the ASP.NET tab. I changed the extension for .axd to run with v2.0… and my JavaScript worked right away.

    Reply

  18. Duke’s avatar

    A few things to check:
    -Does the issue go away with a recycle of the AppPool, or a restart of IIS?
    -Have any additional handlers been added to the site? AJAX perhaps?
    -Does the problem change if the AppPool is switched from Integrated Mode to Classic Mode?

    The last one worked for us.

    Reply

  19. hassan’s avatar

    I had this problem and that reason was incompatibility between Coldfusion and some configurations of ASP.NET applications when IIS App pool is in integrated mode. Coldfusion must be disable .

    Reply