Tuesday, January 19, 2010

WCF Service 401 Intermittent Error (Solution)

Summary:
For a WCF service running on IIS7, the entire service may become inaccessible reporting an HTTP 401 error on every web access, even the main /Service.svc/ and /Service.svc/help URLs. The problem may be that the web.config's aspNetCompatibilityEnabled must be set to "false"

Scenario A (works):
1) web.config / aspNetCompatibilityEnabled="true"
2) iisreset
3) Issue GET request, success (200) (Agent w3wp.exe appears in Task Manager)
4) Issue PUT request, success (200)

Scenario B (fails):
1) web.config / aspNetCompatibilityEnabled="true"
2) iisreset
3) Issue GET request, success (200) (Agent w3wp.exe appears in Task Manager)
3b) Wait 25 minutes (assuming app pool is set to recycle agents after 20 minutes, or do iisreset, agent w3wp.exe disappears from Task Manager)
4) Issue PUT request, failure (401) (See Attachment A below)

Solution:
If at all possible, change your Service's web.config setting aspNetCompatibilityEnabled="false" Even if your app needs it to be true, make the change and redo the test to see if you get by the 401 error. Luckily, my service wasn't using any compatibility features, so I could remove this template default value from my WCF service. This behavior appears to be a bug to me.

The repeatable problem:
When the IIS app pool agent (w3wp.exe) is not running, if a PUT request comes through first, the service will fail with an HTTP 401, and all endpoints of the service will become completely unusable. An iisreset will fix the problem temporarily, but again if the service agent becomes idle for long enough, you may be unluckly enough that a PUT may be the first hit. If a GET is the first hit to the new (or recycled) agent, then the PUT (and other) requests will work properly.

Checking for recycled agent:
1) You could look for that service's w3wp.exe in the task list. Be warned that if you have more than one site/service on that machine they will all look the same.
2) An easy way to determine the first hit on an IIS agent is to look at the IIS log file. The headers are added to the log file when the agent starts up. If the first HTTP hit below the header is unexplicably a 401 (but that hit worked before), then you may have this problem.
3) You could check the "System" event log, it will have an Informational "WAS" event saying: "A worker process with process id of 'NNN' serving application pool 'MyService' was shutdown due to inactivity. Application Pool timeout configuration was set to 20 minutes. A new worker process will be started when needed."

Attachment A: Resulting error

Access is denied.

Server Error in '/' Application.

Access is denied.

Description: An error occurred while accessing the resources required to serve this request. You might not have permission to view the requested resources.

Error message 401.3: You do not have permission to view this directory or page using the credentials you supplied (access denied due to Access Control Lists). Ask the Web server's administrator to give you access to 'C:\inetpub\MyService\Service.svc'.


Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

No comments: