C#.Net error The underlying connection was closed: An unexpected error occurred on a send

If you are using custom C# .Net code to connect to SharePoint Online (Microsoft 365) and suddenly start receiving error message "The underlying connection was closed: An unexpected error occurred on a send.", you have reached the right place, lets fix this together.
You may also see a trace with message "Authentication failed because the remote party has closed the transport stream."

This could be a connection failue from Azure App Service to SharePoint, or custom .Net code (Task Schedular / Windows Service / Console) to SharePoint.

C sharp net error The underlying connection was closed
C sharp net error The underlying connection was closed

⚠️ Why connection failed at System.Net.HttpWebRequest.GetResponse() ?

Most probably, you may be using TLS 1.0 or 1.1 with .Net Framework 4.0 or 4.5 in your C# code.
This is a common problem for legacy applications.

The Transport Layer Security (TLS) 1.0 and 1.1 protocols are deprecated for the Microsoft 365 services. There was temporarily halt due to COVID-19 situation, but TLS 1.2 enforcement is now rolling out.

⭐ What is TLS (Transport Layer Security) ?

Office client relies on Windows web service (WINHTTP) to send and receive traffic over TLS protocols.
Transport Layer Security (TLS) secures communication between computers, most commonly with Hypertext Transfer Protocol Secure (HTTPS). Older protocol versions of TLS are less secure than TLS 1.2 and TLS 1.3 and are more likely to have new vulnerabilities.

Older protocols should be avoided to minimize risk and deprecated security protocols should not be used.

By default, .Net Framework 4.5.1 uses TLS 1.0. Does not matter if the platform supports newer TLS protocol versions. Due to this reason, your custom application cannot connect to SharePoint Online and throws connection exception.

⭐ How to enable TLS 1.2 in C# code ?

  1. Upgrade your application to .NET Framework 4.7.* or newer so it automatically uses TLS 1.2 by default. This is not the easiest approach and may require re-compiling the application.
  2. Manually force the code to use TLS1.2 protocol (System.Net.Http.HttpClient)
  3. ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

  4. Manually specify in code to use either of the TLS protocols (preferred approach)
  5. ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol Or SecurityProtocolType.Tls12 And Not (SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11)

    ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3

  6. Update the associated configuration file to use the strongest available cryptography
  7. <?xml version="1.0" encoding="utf-8"?>
        <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"/>
  8. Update the associate configuration file to use TLS 1.2 by changing the target framework runtime
  9. <configuration>
      <compilation targetFramework="4.5.1" />
      <httpRuntime targetFramework="4.7.2"/>

⚡️ .NET frameworks and TLS support

  • .NET 4.6 and above - Supports TLS 1.2 by default. Upgrade code to this version if possible, this is a long term solution.
  • works well, no changes needed
  • .NET 4.5 - Supports TLS 1.2, but not default. Add below line in your code to make TLS 1.2 as default
  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
  • .NET 4.0 - Does not support TLS 1.2. Install .NET 4.5 or above on the server and use below code to support TLS 1.2.
  • ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
  • .NET 3.5 and below - Does not support TLS 1.2. Upgrade your code to a recent framework.
  • no workaround, only upgrade is a solution

Have Questions? Post them here!
Copyright © Code2care 2024 | Privacy Policy | About Us | Contact Us | Sitemap