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?

  • What do you get with a netstat -a? – Brent Pabst Jun 4 '12 at 16:37
  • There are other sites running on the machine, so netstat shows port 80 in use. Actually figured it out (and I think it's a bug, will chase MS later) answer below. – WaldenL Jun 4 '12 at 17:17

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.

  • Ah, but per my reading of the documentation, the uriprefix must also match, after all, the reservation was for a specific uriprefix space, not the entire space. Also, it seems WCF isn't the only thing to register a wildcard (http://+:80) reservation, branch cache does too. Can't convince me the "design" is that any server with either WCF or a branch cache potential CLIENT (windows 7 machine) should answer with a 404 for a site that isn't defined on that server. – WaldenL Jun 5 '12 at 20:50
  • Yea, it's not the only party crasher. :) Also why site definition in IIS isn't a criteria... The host prefix is used to determine if there's any possible URL Reservation or Registration match, wildcard or otherwise. If there is a match, then the 'host' part of the URL is 'valid'. Else if there is no Reservation or Registration match, then a 400 is returned for 'invalid hostname'. A 503 for Reservation but no Registration match at all (service unavail), and 404 for 'host' Registration match but no uriprefix match (service avail, path is not). No listen means no TCP connection to begin with. HTH – jwp Jun 5 '12 at 22:00
  • Yup, MS claims this is by design too. :-) But given that simply installing WCF, or it seems having a Windows 7 client (because of the branch cache, don't know if that will happen in W2K8/12), causes the server to return a 404 for ANY site, configured on the server or not, I can't believe that's the "correct" behaviour. As for the option of ending the apppool vs. the site, that only helps if there's a 1-1 mapping from site to app pool. Helps me, but may not help all. – WaldenL Jun 6 '12 at 21:13

Is there an active HTTP Module installed on the IIS instance you're not aware of which captures all requests?

Or did you forget that to stop the Default Web site (which comes with a standard IIS installation) active/running, then there is an empty binding.

The Default Web site standard binding is blank which means it accepts all HTTP host headers.

  • Not only is the default site stopped, I actually deleted it just to make sure HTTPSys wasn't doing something daft like seeing the registration for the wildcard binding even it the site was stopped. As for the HTTP Module, if the site is stopped then none of the modules should fire anyway, right? A stopped site should be the same as no site. And I even tried it with a name that doesn't exist, so there was no site entry and it still returned 404. Only when I stop IIS totally (all sites) do I get a reasonable return – WaldenL Jun 4 '12 at 16:04

OK, after an "enjoyable" several hours with MS tech support, we're not in agreement as to whether this is a bug or not, but we are in agreement the problem stems from the presence of the "http://+5000/Temporary_Listen_Address/" which is added by WCF.

As a "workaround" if you add a more specific urlacl for your site in the format of: netsh http add urlacl url=http://hostname:80/ user=networkservice listen=yes delegate=yes

then you will get a 503, not a 404. I maintain this is a "bug", MS is "checking" (not holding my breath).

For those that hit this, the issue # is REG:112060473529066.


OK, figured it out (but I think it's a bug, need to report is to MS later). If I look at the URLACLs listed for HTTPSys using "netsh http show urlacl" I see a registration for "http://+:80/Temporary_Listen_Address/". This SHOULD NOT match the request I'm sending, but it seems to be matching. Per the documentation on UrlPrefix it wouldn't won't match, but per my tests it does.

When I created a new site on port 5000 there was no registration for the temporary_listen_address is all worked as I expected. With two sites (different host headers) running on port 5000 a request for a stopped site returns error 400. However, if I then register a urlacl (netsh http add urlacl) of "http://+:5000/test/" and request something that does not match that url prefix, I get a 404. Remove the registration and I get a 400 again.

I like HTTPSys in general, but it's damn complicated when you dig down into it. Will update w/MS's response later. I don't see a place on connect.microsoft.com to report it so I have to call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.