Error message
SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
Also printed as
- Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
The surrounding chain reads "The SSL connection could not be established" → "Authentication failed, see inner exception." → this message → the OpenSSL reason (for example "error:0A000410:SSL routines::sslv3 alert handshake failure" with OpenSSL 3.0, "ssl/tls alert handshake failure" with 3.3+). On Windows (Schannel) and macOS (Apple's TLS stack) .NET reports such failures with platform-specific messages instead.
.NET on Linux (SslStream over OpenSSL) — inner exception carrying the OpenSSL reason
What it means
On Linux, .NET's SslStream runs on the system OpenSSL, and the handshake failed inside OpenSSL with SSL_ERROR_SSL. This line is a container; the next inner exception (Interop+Crypto+OpenSslCryptographicException) carries the actual OpenSSL reason, such as an alert from the server or a refused protocol version.
Why it happens
No common cipher suite or protocol version
commonLegacy servers with RSA key exchange, 3DES or TLS 1.0/1.1 only; the OpenSSL reason shows the alert the server sent.
The server required a client certificate
occasionalTLS 1.2 mutual-TLS servers answer a missing certificate with a handshake_failure alert.
The system OpenSSL policy forbids what the server needs
occasionalDistribution defaults (security level 2, TLS 1.2 minimum) apply to .NET on Linux too; the same app may work on Windows and fail in a Linux container.
How to fix it
- 1.
Read the OpenSSL reason in the innermost exception
The error:0A… code and text identify the problem; map it as shown.
text Interop+Crypto+OpenSslCryptographicException: error:0A000410:SSL routines::sslv3 alert handshake failure -> the server rejected the offered suites/versions (or wants a client certificate) error:0A00042E:SSL routines::tlsv1 alert protocol version -> the server only speaks TLS 1.0/1.1 error:0A00018A:SSL routines::dh key too small -> the server uses 1024-bit DH - 2.
Compare server and client capabilities
Enumerate the server's suites and the local OpenSSL defaults.
bash nmap --script ssl-enum-ciphers -p 443 legacy.example.com # what the server offers openssl ciphers -v 'DEFAULT' | head # what this system's OpenSSL offers - 3.
Fix the server, not the client policy
Modernise the server's TLS configuration; relax the client's OpenSSL policy only as a narrow, temporary exception.
text Server side: enable TLS 1.2/1.3 with ECDHE + AES-GCM (or ChaCha20) suites. Lowering the system-wide OpenSSL policy (CipherString=DEFAULT@SECLEVEL=1 in openssl.cnf) affects every application on the host and should only be a short-lived exception for an isolated legacy peer.