Could not establish trust relationship for SSL/TLS secure channel -- SOAP

I have a simple web service call, generated by a .NET (C#) 2.0 Windows app, via the web service proxy generated by Visual Studio, for a web service also written in C# (2.0). This has worked for several years, and continues to do so at the dozen or so places where it is running.

A new installation at a new site is running into a problem. When attempting to invoke the web service, it fails with the message saying:

Could not establish a trust relationship for the SSL/TLS secure channel

The URL of the web service uses SSL (https://) -- but this has been working for a long time (and continues to do so) from many other locations.

Where do I look? Could this be a security issue between Windows and .NET that is unique to this install? If so, where do I set up trust relationships? I'm lost!


The following snippets will fix the case where there is something wrong with the SSL certificate on the server you are calling. For example, it may be self-signed or the host name between the certificate and the server may not match.

This is dangerous if you are calling a server outside of your direct control, since you can no longer be as sure that you are talking to the server you think you're connected to. However, if you are dealing with internal servers and getting a "correct" certificate is not practical, use the following to tell the web service to ignore the certificate problems and bravely soldier on.

The first two use lambda expressions, the third uses regular code. The first accepts any certificate. The last two at least check that the host name in the certificate is the one you expect.
... hope you find it helpful

//Trust all certificates
System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

// trust sender
System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

// validate cert by calling a function
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
    bool result = cert.Subject.Contains("YourServerName");
    return result;
}

The very simple "catch all" solution is this:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

The solution from sebastian-castaldi is a bit more detailed.


Thoughts (based on pain in the past):

  • do you have DNS and line-of-sight to the server?
  • are you using the correct name from the certificate?
  • is the certificate still valid?
  • is a badly configured load balancer messing things up?
  • does the new server machine have the clock set correctly (i.e. so that the UTC time is correct [ignore local time, it is largely irrelevent]) - this certainly matters for WCF, so may impact regular SOAP?
  • is there a certificate trust chain issue? if you browse from the server to the soap service, can you get SSL?
  • related to the above - has the certificate been installed to the correct location? (you may need a copy in Trusted Root Certification Authorities)
  • is the server's machine-level proxy set correctly? (which different to the user's proxy); see proxycfg for XP / 2003 (not sure about Vista etc)

I personally like the following solution the most:

using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

... then before you do request getting the error, do the following

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

Found this after consulting Luke's Solution