401 Client 'Negotiate', Server 'Negotiate,NTLM' When Calling WCF Server to Server

To answer the first question, the error message is telling me exactly what it says; I'm not authorized. The line telling me the client authentication scheme and server header is just extra info, not an indication of a conflict. It's actually confirmation that the configuration is correct.

In the staging environment, the problem is being masked because the WCF service and the web application are hosted on the same server. The problem is the web app's site is configured to use IUSR (or IUSR_Server), a local account, for anonymous users by default. This is the user that is being passed (which I believe is equal to CredentialCache.DefaultNetworkCredentials). When they're on different servers, WCF on server 2 obviously can't authenticate a server 1 user. The solution is in IIS, right click Anonymous Authentication > Edit...> check Application pool identity (which is a domain account in my case) or enter a domain account for Specific user.


It just means your client and server are using different authentication scheme.

In your client config, you've set up a

<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />

and a message security

<message clientCredentialType="UserName" algorithmSuite="Default" />

So you might be getting errors because of this. These links might help you.

  • Ch. 7 Message and Transport Security
  • security of basicHttpBinding

Also, in your client config

<endpoint address="https://.../QueueService.svc" binding="basicHttpBinding" bindingConfiguration="QueueSecuredEndpoint" behaviorConfiguration="OMSServiceBehavior" contract="OMQueueService.IQueueService" name="QueueSecuredEndpoint" />

Change the behaviorConfiguration from behaviorConfiguration="OMSServiceBehavior" to behaviorConfiguration="OMWebServices.QueueServiceBehavior"

Also did you try to use TransportCredentialOnly? If not, it might be good to try this http://msdn.microsoft.com/en-us/library/ff648505.aspx

<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Windows" />
</security>

My problem with this error was not config related but specific to a WCF Service calling another on the same machine.

Because this affected a fleet of new servers that were partly provisioned through a C# console app, I solved it by executing code like this through the affected servers:

const string userRoot = "HKEY_LOCAL_MACHINE";
const string subkey = @"SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0";
const string keyName = userRoot + @"\" + subkey;
Registry.SetValue(keyName, "BackConnectionHostNames", hostnamesOnServer.ToArray(), RegistryValueKind.MultiString);

Reboot wasn't required on Windows Server 2012.