IIS 7.5 returning 404 for unknown host names

iisiis-7.5windows-server-2008-r2

This just doesn't seem correct to me, so I'm looking for someone to tell me how I've misconfigured IIS… Configuration is IIS7.5 (2008R2), without SP1.

I have IIS 7.5 configured w/several sites. ALL sites have hostnames defined in the bindings, there is NO site w/out a hostname. However, if I request an unknown hostname from the server IIS (technically Microsoft-HTTPAPI/2.0) return a 404 error, not a 400 error. I would expect a 400 (or some other major error) rather than a lowly 404.

This causes a problem when I have nginx in front of multiple IISs and want to stop a site so nginx takes it out of rotation. Since IIS still returns a 404 for the request even when there is no active site for that name, nginx doesn't know the server is dead.

NB: IIS returns the 404 regardless of whether there is a server, but it's stopped, or there is no server.

Thoughts? Solutions?

— Additional info: OK, I added a site on a port other than 80 (5000) and then on a connection to that port asked for a site that doesn't exist, and I get the expected error 400 (Invalid hostname). So, while IIS isn't listening for generic (no host name) connections on port 80 it would seem that something is. Any ideas how to get HTTPSys to dump the list of what it's listening for?

Best Answer

This is by design. A URL Reservation is not the same as a URL Registration, which happens dynamically when an application registers with HTTP.SYS to being listening. In the case of a URL Reservation, HTTP.SYS does not know whether the URL in a given Reservation is simply unavailable temporarily or does not exist at all. All it can know in this case is that there is a valid host name match (because of your strong/weak wildcard), but the URL path does not match for any currently registered listeners.

If you want a 400 or 503 response, then either do not use any URL Reservation, or use explicit URL Reservations that do not include wildcards. In short, if you configure HTTP.SYS such that it can match the prefix of the URL to any Reservation (including dynamic ones created via Registration), then it will either deliver the request to listening application (if the rest matches), or return a 404 if it can't find an active registered listener.

Another solution that may be simpler is to use the IIS service itself to manage sending a 503. To do this don't stop the site, but instead stop the Application Pool(s) associated with it. This will cause a fully qualified match to occur in HTTP.SYS (even with wlidcard URL Reservations), but will result in a 503 because there is no AppPool to deliver the request to.