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.
Comments
Dave
This does not work for me. Running a Windows .NET 4.8 Desktop application with this line of code:
April 25, 2023System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls13;
I added the new line to the app.config file and the error still occurs:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls13;
Dave
Sorry, error is:
April 25, 2023System.Net.WebException
HResult=0x80131509
Message=The request was aborted: Could not create SSL/TLS secure channel.
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
Jonathan Crozier
Hi Dave,
It could be that the TLS 1.3 protocol is not enabled on the machine. Can you tell me what operating system the desktop application is running on?
According to the following article, TLS 1.3 isn’t enabled by default on current versions of Windows 10. The article provides instructions on how to resolve this.
https://www.asustor.com/en-gb/knowledge/detail/?id=&group_id=1011
Please let me know if this fixes the issue for you or if you are still having problems.
April 26, 2023Kadir Cobas
You save my day!
October 16, 2023Jonathan Crozier
I’m glad to hear that! 🦸♂️ 😊
October 16, 2023