Search code examples
.netwcfiis-7windows-server-2008windows-authentication

IIS7 Windows authentication causes 0x2746 SocketException


I am hosting a WCF service under IIS7 on Win2008R2. It runs fine for weeks, and then when we do anything like a server restart, usually due to a deployment, it starts off encountering an error as follows:

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Basic realm="myrealm.local",Negotiate,NTLM'. System.Net.WebException: The remote server returned an error: (401) Unauthorized.

I've tried restarting all the software to no effect. I then restart the server itself, and it changes into an error stating:

[SocketException (0x2746): An existing connection was forcibly closed by the remote host] [IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.] [WebException: The underlying connection was closed: An unexpected error occurred on a send.] [CommunicationException: An error occurred while making the HTTP request to *. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.]

The IIS logs show only that it is giving a 401 response. WFetch shows a message '0x2746 [sockslip]: recv()'

I've ruled out the client, the service software itself, directory permissions on the server, and the networking.

If I switch on Anonymous Authentication, it all works; turn it off with only Windows Authentication enabled, and it fails.

This looks like an IIS7 authentication problem, but I don't know how to trace this down, as the WCF trace doesn't show any clue, and no exceptions are logged on the server.

CLARIFY In the past the problem has actually seemingly disappeared by itself, however I have found that once the service has been accessed with Anonymous switched on, when it is then switched off, the service continues to work in Windows authentication until the next restart.

Regards, Rob.


Solution

  • Okay, it turns out this is one of the more misleading Microsoft error messages I've come across.

    The socket exception occurs when you are trying to access an application folder nested underneath another application folder or website.

    E.g.

    Website A
    |
    |--> Application B
    

    If the authentication settings at A are misconfigured, or have a problem, when you try to access B directly, you get the socket exception instead of the real answer. It seems IIS can't report the error back from the application you are trying to access, as it has been unable to "drill through" the underlying site structure.

    To get rid of the socket exception and to see the real 401 exception, I simply enabled Anonymous authentication at A, allowing any issues at that level to be bypassed, and causing the error to come from application B instead.


    The 401 authentication error is being created on the initial request without any exception being logged in the event viewer.

    The answer appears to be the use of system.webServer -> httpErrors

    As I wanted to use the tilde (~) in the URL, I was setting my config to the following:

    <httpErrors>
      <clear />
      <error statusCode="401" responseMode="ExecuteURL" path="~/error.xml" />
    </httpErrors>
    

    Whether it was the use of tilde, or the ExecuteURL, I eventually found that using the following works:

    <httpErrors>
      <clear />
      <error statusCode="401" responseMode="File" path="/error.xml" />
    </httpErrors>