The Importance of Understanding the Config System

 While teaching an IIS7 class two weeks ago, I ran across an issue that proved a bit interesting to troubleshoot. This is actually the second time that at least one participant hit this issue in class, but it was the first time it could be blamed on the instructor :). In any case, it was a good reminder to check your work when editing the IIS configuration directly. It also shows that understanding how the new IIS configuration system works can prove invaluable. Here's the scenario:

We were turning IIS into a streamlined static content server, and unloading all modules deemed unnecessary for the task. This left us with <globalModules> and <modules> sections that looked like so:

    <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
    <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />

    <add name="AnonymousAuthenticationModule" />
    <add name="StaticFileModule" />

After making this change, I had two things for them to try. The first was to hit a static page in the site directly, which worked fine. The second was to browse the root of the site (http://localhost/) to see what happened. I was expecting the second hit to result in a blank browser window, but in most cases, the students were seeing IE's generic 500 error. What I came to realize is that the 500 was occurring because I forgot one very important step in the lab, which we'll get to shortly. My mistake gave me the opportunity to show how important it is to know the config system, and to ensure you have the necessary modules loaded to troubleshoot problems like this.

So the first question: Why were we getting IE's generic 500 error, and not one of the nice detailed errors IIS 7.0 throws? Well, when you remove the custom error module, IIS has no way of returning those detailed errors. Additionally, we'd unloaded the Failed Request Tracing module, so that feature wasn't available to us for troubleshooting either. Sure, we could add either of them back in and we'd have our answer right away, but where's the fun in that?

On to the second and most important question: Why were we getting the 500? Well, the two config sections we modified above looked right, and there was in fact nothing wrong with them. We (and by "we", I mean ‘I') spent a little too much time focusing on those two sections and making sure people had typed them in properly. After a bit I decided that I'd focus on the issue during a break so we didn't delay the class too long. When we hit the break and I took a closer look, it took all of 5 minutes to figure out where we'd gone wrong.

The cause? Early on in the lab when we were editing the config, I'd forgotten to strip down the handlers section like the lab steps dictated. Had I done that, it should have looked like this:

    <add name="StaticFile" path="*" verb="GET,HEAD"  modules="StaticFileModule" resourceType="Either" requireAccess="Read"/>

Instead, the StaticFile entry within the handlers section of our config actually looked like this:

<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />

Anyone figure out the problem yet? Notice how that entry has two additional modules mapped to it that don't appear in the first entry I pasted (DefaultDocumentModule,DirectoryListingModule)? When we were hitting the site via localhost and not specifying a page name, the StaticFile handler was attempting to load one of those two since it had no idea what I wanted. Neither of those modules are present in the globalModules or modules sections, so IIS can't load either, and throws the 500. Had I followed the lab steps when walking the students through the changes we needed to make in applicationHost.config, we could have avoided this, but in the end it turned out to be a good lesson in config structure and how the different sections work together.

No Comments