.NET Error – The request was aborted: Could not create SSL/TLS secure channel.

When using a .NET application that communicates with a web server, you may encounter the following error.

The request was aborted: Could not create SSL/TLS secure channel.

This exception message typically indicates that a secure channel could not be created due to the client application failing to specify a cryptographic protocol that is supported by the server.

If you are dealing with a .NET application for which you do not have access to the source code in order to recompile it, you can usually resolve the problem with a simple configuration file change instead.

In this post, I explain how to update the configuration of the application to resolve this particular issue.

Issue background

The ‘request was aborted’ error described above is an exception that can be thrown by methods of the WebRequest and WebClient classes. For example, the DownloadFileAsync method.

As time goes on, this issue is more likely to crop up, as an increasing number of servers remove support for the older TLS 1.0 and TLS 1.1 protocols. At the time of writing, TLS 1.2 and TLS 1.3 are the current standards for secure network communications.

If you come across this issue, it will usually be a .NET Framework application that is raising the error, as opposed to .NET Core. By default, older .NET Framework versions do not specify that more modern versions of cryptographic protocols such as TLS 1.2 and TLS 1.3 should be used.

Before showing you the configuration file fix, let me briefly make you aware of two other possible ways of correcting the issue if you happen to own the affected application.

.NET Framework upgrade

The problem is addressed in newer versions of the .NET Framework, without requiring any code changes. For example, if you are using .NET 4.7 or greater, your application will automatically select the most secure protocol by querying the operating system before a web request is made.

If you’re able to update the .NET Framework version to v4.7 or greater, then aside from deploying a new version of the application, you’ve nothing else to do.

Code changes

If you have access to the source code for the application and for some reason you cannot upgrade the .NET Framework version, it is possible to manually specify the cryptographic protocols to use, as per the following code.

ServicePointManager.SecurityProtocol = 
SecurityProtocolType.Tls12 | 
SecurityProtocolType.Tls11 | 
SecurityProtocolType.Tls;

Note that ServicePointManager requires a using statement for the System.Net namespace.

The code that sets the SecurityProtocol should be called soon after your application has started and before any web requests are attempted. Usually, this would be in the Main method of your Program class, or in a method that gets called shortly after application startup to configure the application.

Note that if one or more of the specified TLS protocols are not supported, the code will throw an exception. For example, when running on an old operating system such as Windows XP.

The above code will compile for projects that are targeting .NET 4.5 or greater.

If your project is targeting an older .NET Framework version such as 4.0, you will need to specify numeric values for TLS versions that do not exist in the targeted .NET version libraries, as follows.

ServicePointManager.SecurityProtocol = 
    (SecurityProtocolType)3072 | // TLS 1.2
    (SecurityProtocolType)768  | // TLS 1.1
    (SecurityProtocolType)192;   // TLS 1.0

Note that in .NET 4.0 SecurityProtocolType.Tls (TLS 1.0) is the newest available protocol. For .NET 4.0 the above code could be changed to specify Tls instead of 192 and it would still compile.

It is important to bear in mind that even though the above code compiles in .NET 4.0, it will only work on a machine that has .NET 4.5 or greater installed on it.

One of the problems with the above code is that it ties the application down to using only the specified security protocols, thereby preventing the application from using another protocol such as TLS 1.3 in the future. However, this is manageable if you have access to the source code and are able to redeploy the application later down the line.

In the next section, I’ll cover a non-intrusive way of correcting the issue which doesn’t involve changing code and recompiling/reinstalling the software.

Configuration file

Sometimes it isn’t possible (or practical) to change and redeploy the affected application. Despite this, the issue can be fixed in most cases with a simple configuration file update.

Note that this solution will only work on .NET 4.5+ applications running on Windows 8+ devices.

Most .NET Framework applications are deployed with an XML configuration (app.config) file that can be used to configure many different aspects of how the application behaves at runtime.

The configuration file is always named after the main application executable file with a ‘.config’ extension and should exist in the same directory as said executable. For example, an application with a main executable file named ‘MyApp.exe’ will have a corresponding configuration file named ‘MyApp.exe.config’.

Suppose the application you are using doesn’t have a configuration file already. In that case, you can create one according to the naming convention specified above i.e. APP_NAME.exe.config and then paste in the following as its contents.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"/>
  </runtime>
</configuration>

If the application already has a configuration file it should have a ‘configuration’ element in it and may already contain a ‘runtime’ element (if it doesn’t then create the appropriate opening and closing tags for the element). Add the self-closing ‘AppContextSwitchOverrides’ element as per the above example and save the file.

Restart the application and you should now find that the ‘request was aborted’ error is no longer occurring.

Summary

In this post, I have documented how to fix the ‘request was aborted’ error that you may encounter when running applications that are targeting older versions of the .NET Framework.

I explained the background of the issue and how it can be resolved if you have access to the source code.

I then demonstrated how to resolve the problem in a non-invasive way that doesn’t require recompilation and reinstallation of the affected application by making a simple configuration change.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments

This site uses Akismet to reduce spam. Learn how your comment data is processed.