I saw a problem today where a customer was unexpectedly getting 503 errors when attempting to access a directory named /Reports in an application in IIS, which was running on a server that also had Reporting Services 2008 R2 installed.
I verified that the application pool was running and that there were no errors written to the application or system logs around the time of the failing requests. 503s are almost always due to a crashing or stopped application pool in my experience, so this finding surprised me.
The only clue in logs I could find were lines like the following in httperr.log:
2013-01-03 14:24:01 192.168.1.10 42291 10.8.7.6 80 HTTP/1.1 GET /Reports/MyReport.aspx 503 - N/A -
2013-01-03 14:24:02 192.168.1.10 42292 10.8.7.6 80 HTTP/1.1 GET /Reports/MyReport.aspx 503 - N/A -
2013-01-03 14:30:52 192.168.1.10 33052 10.8.7.6 80 HTTP/1.1 GET /Reports/MyReport.aspx 503 - N/A -
2013-01-03 14:30:54 192.168.1.10 33056 10.8.7.6 80 HTTP/1.1 GET /Reports/MyReport.aspx 503 - N/A -
2013-01-03 14:32:34 192.168.1.10 33179 10.8.7.6 80 HTTP/1.1 GET /Reports/MyReport.aspx 503 - N/A -
One thing that stood out is the lack of information in the 503 errors in this case. 503 errors in httperr.log usually have some additional fields populated, like this:
2009-07-26 13:29:29 127.0.0.1 49165 127.0.0.1 80 HTTP/1.1 GET /page.asp 503 1 AppOffline DefaultAppPool
The lack of information in the substatus code and other fields appears to be related to HTTP.sys routing the request to an application that isn’t running. This is caused by URL reservations, which you can list out with the following command:
netsh http show urlacl
The problematic URL reservation was the following one that Reporting Services creates as part of its default configuration:
Reserved URL : http://+:80/Reports/
User: NT AUTHORITY\NETWORK SERVICE
URL reservations are also logged in the system log under the category HttpEvent when created, for example:
Log Name: System
Date: 1/1/2013 12:08:32 AM
Event ID: 15007
Task Category: None
Reservation for namespace identified by URL prefix http://+:80/Reports/ was successfully added.
Web servers that want to receive HTTP requests through HTTP.sys create URL reservations to tell HTTP.sys where to send the HTTP requests.
This reservation was matching requests for /Reports that the user intended to send to the client’s application hosted in IIS. Since the Reporting Services service was stopped, HTTP.sys was trying to hand the request to Reporting Services but failing and returning 503. If it had been running, I assume we’d have been getting 404s instead since no page named MyReport.aspx exists in SSRS.
To fix the problem, I ran the SSRS configuration wizard to change the Report Manager URL, and then HTTP.sys routed requests for the customer’s application as expected. Of course normally you wouldn’t want to just change that without planning, but this case the client wasn’t even using SSRS.
A similar problem is discussed here.
I’m still trying to work out how HTTP.sys determines what application the request is for. I understand that a service SID can be part of the reservation, but there doesn’t appear to be one for the reservations that SSRS creates. If anyone knows the answer, please comment.