title: .net httpclient on Azure w/ TLS/SNI: The request was aborted: Could not create SSL/TLS secure channel
body: <p>Similar questions have been asked multiple times before - but before flagging this one as duplicate please read on. Most of these questions are very old. I have worked through a lot of questions and answers and did not find a suitable solution.</p>
  <p>We have an Azure Cloud Service project in .net 4.5. It connects to dozens of our customers' APIs (not necessarily cloud hosted) without any problems, but a single API fails with this error message:</p>
  <p><strong>The request was aborted: Could not create SSL/TLS secure channel</strong></p>
  <p>What am I missing here?</p>
  <p>This is the code (slightly condensed) that I am using to connect to the API (this runs per API, so the base URL does not change):</p>
  <pre><code>ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
  ServicePointManager.Expect100Continue = true;
  ServicePointManager.SecurityProtocol =
      SecurityProtocolType.Tls12 |
      SecurityProtocolType.Tls11 |
      SecurityProtocolType.Tls |
      SecurityProtocolType.Ssl3;
  
  ApiClient = HttpClientFactory.Create();
  ApiClient.DefaultRequestHeaders.Authorization = null;
  ApiClient.DefaultRequestHeaders.TryAddWithoutValidation(&quot;Authorization&quot;, &quot;Basic {passwordToken}&quot;);
  ApiClient.DefaultRequestHeaders.Accept.Clear();
  ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&quot;application/json&quot;));
  
  SemaphoreSlim throttler = new SemaphoreSlim(initialCount: 50);
  
  var sp = ServicePointManager.FindServicePoint(new Uri(baseUrl));
  sp.SetTcpKeepAlive(true, 30000, 30000);
  
  foreach (var request in urls)
  {
      Result = new HttpResponseMessage();
      Result = await ApiClient.GetAsync(url);
      ...
  }
  </code></pre>
  <p>This is what makes it hard to debug:</p>
  <ul>
  <li>This problem <strong>only</strong> occurs in production, i.e. when running as an Azure Cloud Service. Not when debugging locally.</li>
  <li>It only occurs with requests sent through HttpClient. Not with WebClient.</li>
  <li>Further research (comparing the APIs) revealed that <strong>this API is the only one that has enabled SNI and ONLY supports TLS1.2.</strong></li>
  </ul>
  <p>Suggestions considered from other questions/answers regarding SNI in .net Framework:</p>
  <ul>
  <li>To prevent misunderstandings: This is about the cloud service connecting to an API, not about a connection that is being made to the cloud service.</li>
  <li>The HttpClient instance is being reused for all requests to a single API. (This is important as <a href="https://stackoverflow.com/a/39706609/9271486">this answer</a> suggests that the SNI tag will be created with the domain HttpClient has been initialized with). <a href="https://stackoverflow.com/a/50977774/9271486">I have also tried configuring TLS after the Factory instantiated the HttpClient</a>. No change.</li>
  <li>The certificates are valid of course. No self-signed certificates but regular trusted ones off the shelf. Opening the API in any browser also works like a charm.</li>
  <li>TLS1.2 is not enabled by default in .net framework 4.5, but the line <code>ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12</code>should actually enable it. Is there anything wrong with the way I am doing it?</li>
  <li>Calling the API in curl (WSL and Azure remote bash) with <code>curl --user 'user:pwd' https://myurl</code> also works perfectly and returns the expected data.</li>
  <li>Testing tls1.2 with openssl like <code>openssl s_client -connect hostname:443 -tls1_2</code> does not reveal any issues. The chain is displayed correctly, and a TLSv1.2 session is confirmed. Testing the server's SNI feature with openssl with <code>openssl s_client -connect host:443 -tls1_2 -servername host -tlsextdebug -msg</code> reveals SNI support by returning <code>TLS server extension &quot;server name&quot; (id=0), len=0</code> I get the same certificate if I provide a completely different fantasy hostname though.</li>
  <li>I captured the TLS/SNI handshake when debugging locally (see screenshot below). No issues. My ability to debug ends with the cloud service. I would love to see the handshake between the cloud service and the API in WireShark, but I don't know of any option to analyze network traffic at that layer on an Azure cloud service. But if anyone knows how to capture the handshake process, I'd appreciate some hints.</li>
  <li>The server selects ECDHE-RSA-AES256-GCM-SHA384 as a cipher suite during the handshake with openssl which is pretty much default for TLS1.2. I don't have access to the cloud services list of cipher suites that it would provide at Client Hello - any idea how to find out?</li>
  <li>I don't have any proof that SNI is actually causing the problem, but this is the only difference between this API and dozens of others I can spot.</li>
  </ul>
  <p><a href="https://i.stack.imgur.com/0TtFw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0TtFw.png" alt="TLS/SNI handshake captured locally in WireShark" /></a></p>
  <p>Stack trace:</p>
  <blockquote>
  <p>System.Net.Http.HttpRequestException: An error occurred while sending the request. ---&gt; System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.     at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)     at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)     --- End of inner exception stack trace ---     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)     at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()     at WCFServiceWebRole1.Controllers... in [the line calling GetAsync()]</p>
  </blockquote>