The TLS handshake failed because the client and server couldn’t agree on any common encryption algorithms.
This usually happens when one side is configured to only support very old, insecure cipher suites, or when a modern server is locked down to only use strong ciphers that the client simply doesn’t have implemented.
Here are the common causes and how to fix them:
Cause 1: Outdated Client Software
An old client might not support modern TLS versions or strong cipher suites.
Diagnosis: Check the client’s TLS version support. For OpenSSL, you can use openssl s_client -connect example.com:443 -tls1_2 to test specific versions. If it fails, try older versions like -tls1_1 or -ssl3.
Fix: Upgrade the client software to a recent version that supports TLS 1.2 or TLS 1.3. For example, if you’re using an older Java version, upgrade to Java 8u291+ or Java 11+.
Why it works: Newer client versions include support for a wider range of modern, secure cipher suites and TLS protocols, increasing the chance of finding a common ground with the server.
Cause 2: Server is Too Restrictive (Modern Server, Old Client)
The server has been configured to only accept TLS 1.2 or TLS 1.3 with very specific, strong cipher suites, and the client doesn’t have them.
Diagnosis: Examine the server’s TLS configuration. For Nginx, this is typically in /etc/nginx/nginx.conf or a site-specific conf file, specifically the ssl_ciphers directive. For Apache, it’s SSLCipherSuite in your SSL configuration.
Example Nginx ssl_ciphers:
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off; # Important for compatibility
ssl_protocols TLSv1.2 TLSv1.3;
Example Apache SSLCipherSuite:
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 # Ensure TLSv1.2 and TLSv1.3 are enabled
Fix: Broaden the ssl_ciphers or SSLCipherSuite list on the server to include more commonly supported, albeit potentially slightly less strong, cipher suites. You can also set ssl_prefer_server_ciphers off; (Nginx) or remove + from SSLCipherSuite (Apache) to let the client’s preference take precedence, which often leads to a successful negotiation if the client has any compatible suite.
Why it works: By including a wider variety of cipher suites, you increase the probability that the client’s implemented cipher suites will overlap with the server’s allowed list. Disabling server preference allows the client to pick a suite it can use.
Cause 3: Server is Too Restrictive (Old Server, Modern Client)
The server is configured to only support very old TLS versions (e.g., TLS 1.0, TLS 1.1) or very old cipher suites, and the modern client has disabled these for security reasons.
Diagnosis: Again, check the server’s ssl_protocols (Nginx) or SSLProtocol (Apache) directives. For Nginx, it might look like ssl_protocols TLSv1 TLSv1.1;. For Apache, SSLProtocol TLSv1 TLSv1.1.
Fix: Update the server’s SSL/TLS configuration to enable TLS 1.2 and TLS 1.3. For example, in Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
And in Apache:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
Why it works: This forces the server to use modern, secure protocols that modern clients are configured to support, resolving the incompatibility.
Cause 4: Intermediate Proxy or Firewall Interference
A network device between the client and server might be interfering with the TLS handshake, stripping out cipher suites or TLS versions.
Diagnosis: Use tcpdump on both the client and server sides to capture the TLS handshake packets. Look for differences in the ClientHello and ServerHello messages. You can also try bypassing any intermediate proxies if possible.
Fix: Configure the intermediate device to allow the necessary TLS versions and cipher suites. This might involve updating firmware or modifying security policies on the firewall or proxy.
Why it works: Network devices can sometimes be misconfigured to block certain handshake parameters, and correcting their configuration allows the client and server to communicate the full range of their capabilities.
Cause 5: Incorrect SSL/TLS Configuration for Specific Libraries
Sometimes, specific applications or libraries have their own SSL/TLS context that might be misconfigured independently of the system-wide settings.
Diagnosis: If you’re using a specific client library (e.g., Python’s requests, Java’s HttpClient, curl with a particular build), check its documentation for how to control TLS versions and cipher suites. For curl, you can specify TLS versions with --tlsv1.2 or --tlsv1.3.
Fix: Ensure the library’s configuration aligns with supported protocols and cipher suites. For example, if using Python’s ssl module, you might explicitly set ssl.PROTOCOL_TLSv1_2.
Why it works: Different libraries can have different default SSL/TLS settings or require explicit configuration to enable modern protocols and cipher suites, overriding or supplementing system defaults.
Cause 6: SNI (Server Name Indication) Issues
While less common for "No Shared Cipher" specifically, SNI problems can sometimes lead to the server presenting the wrong certificate or an incomplete cipher suite list if it’s not configured correctly for multiple domains.
Diagnosis: Ensure the server_name directive in Nginx or ServerName/ServerAlias in Apache are correctly set for the hostname the client is trying to reach.
Fix: Correct the server_name or ServerName/ServerAlias directives to match the hostname used in the client’s request.
Why it works: SNI allows a server to host multiple SSL/TLS certificates on a single IP address. If the server doesn’t correctly identify the requested hostname, it might use a default configuration that doesn’t match the client’s expectations or capabilities.
The next error you’ll likely encounter after fixing this is a certificate validation error, as the handshake will now complete but the client might not trust the server’s presented certificate.