C# HttpWebRequest The underlying connection was closed: An unexpected error occurred on a send
In 4.0 version of the .Net framework the ServicePointManager.SecurityProtocol
only offered two options to set:
- Ssl3: Secure Socket Layer (SSL) 3.0 security protocol.
- Tls: Transport Layer Security (TLS) 1.0 security protocol
In the next release of the framework the SecurityProtocolType
enumerator got extended with the newer Tls protocols, so if your application can use th 4.5 version you can also use:
- Tls11: Specifies the Transport Layer Security (TLS) 1.1 security protocol
- Tls12: Specifies the Transport Layer Security (TLS) 1.2 security protocol.
So if you are on .Net 4.5 change your line
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
to
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
so that the ServicePointManager will create streams that support Tls12 connections.
Do notice that the enumeration values can be used as flags so you can combine multiple protocols with a logical OR
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
Note
Try to keep the number of protocols you support as low as possible and up-to-date with today security standards. Ssll3 is no longer deemed secure and the usage of Tls1.0 SecurityProtocolType.Tls
is in decline.
I experienced this exception, and it was also related to ServicePointManager.SecurityProtocol
.
For me, this was because ServicePointManager.SecurityProtocol
had been set to Tls | Tls11
(because of certain websites the application visits with broken TLS 1.2) and upon visiting a TLS 1.2-only website (tested with SSLLabs' SSL Report), it failed.
An option for .NET 4.5 and higher is to enable all TLS versions:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12;
For .Net 4 use:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072;