Windows 2003 Server ships with version 6 of the IIS web server. Microsoft have (at long last) been pretty sensible in making a default installation of IIS run with all possible options locked down. By default it will serve only static content – not even ASP.
This is good news as it means that carelessly installed/configured servers are a lot more secure. For anyone who makes use of ASP or include files (another locked-down option) this simply means that you have to go to the IIS console on the server and enable these technologies. An easy step.
However, (could you see the ‘but’ coming?) in its locked down state, IIS does little to inform the user or system administrator why their ASP page will not load. Calling an ASP page results in an HTTP 404 error – File Not Found. What the heck? The file has been found, but IIS is set not to run it. Surely this is the wrong error code to issue?
So I looked at the spec and sure enough, the 404 error code doesn’t seem to fit this situation. Naturally, I hunted around for a better match and didn’t have to go far to find one:
403 Forbidden
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity.
All good so far. It looks like 403 should be a perfect match for this situation. IIS understands the request, but is locked down and so is refusing to process an ASP page. It even has the option to explain that ASP is disabled to let the system administrator know what’s going on. But that’s not the full description of 403 – it goes on to say this:
If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
What?! How stupid is that?! The file is forbidden but the server doesn’t want to explain why, so it pretends it’s missing? Where’s the logic in that? How does that help a developer or administrator fix the problem? I’ve said it before and I’ll say it again – has the whole world lost its head?
On the face of it, it would seem that Microsoft are justified in issuing a 404 when ASP is locked down. I can’t help but think this is only because the spec is completely insane. I wonder how many thousands of hours will be wasted globally as ASP sites are moved onto new Windows 2003 Servers and good, hardworking folk spend a significant part of their day figuring out why their files cannot be found. All because someone and Microsoft couldn’t be bothered to type out a new error message. Power brings with it great responsibility.
Update: as pointed out by Harold in the comments below, an even more appropriate error message would be 501 – Not Implemented. The fact that it starts with a 5 indicates that it’s an error at the server, and not a problem originating from the client. What this means is that Microsoft were even further from the mark than I gave them credit for – the error shouldn’t even be 4xx class, it should be 5xx class. Thanks Harold.



Comments
A 4xx status code denotes an error on the client side (ie. a malformed request, wrong url, wrong password, etc.).
Status codes in the 500 tange denote a fault at the serverside. Often misconfigured perl/cgi scripts will lead to 500 errors.
Here’s a snippet from the specs:
This seems to suggest that if the server is aware that serverside code has been disabled it should issue a 501 status code.
As an aside, the server at my place of work, a library, uses 403 status codes when denying access to (copyright protected) resources that are only available to internal IP adresses, there is no authentication method other that the IP adress of the client. This is the only place I’ve ever seen a 403 statuscode.
Definitely a *poor* choice of error messages...
Thanks!
Been triying to figure wtf was going on for more than half an hour, very helpful post :)
Is there some reason IIS doesn’t allow the HEAD Request, by returning the 403 error on asp as well as php pages?
It turns out that the default action of a head request on IIS is 403 and my host (web.com) wouldn’t reconfigure. This is nonsense so I moved my site to LAMP. In the process I created an extension for firefox that checks headers. (HeaderGetter)
Might be useful…