The SSL handshake is failing because the client and server can’t agree on a common set of cryptographic algorithms or parameters necessary to establish a secure connection.

Common Causes and Fixes for SSL Alert Number 40 (Handshake Failure)

This error means the SSL/TLS handshake between your client and the server has collapsed. It’s not just a simple timeout; it’s a fundamental disagreement on how to secure the communication channel, usually stemming from incompatible cipher suites, protocol versions, or certificate issues.

  1. Cipher Suite Mismatch: The most frequent culprit. Your client (e.g., web browser, curl) and the server support different sets of encryption algorithms (cipher suites). The handshake fails because they can’t find a common suite they both agree to use.

    • Diagnosis: On the server-side (if you control it, e.g., Apache, Nginx), check your SSL configuration file. For example, in Nginx, look for the ssl_ciphers directive.
      # Example Nginx ssl_ciphers directive
      ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256;
      ssl_prefer_server_ciphers on;
      
      You can test your server’s supported cipher suites using openssl s_client:
      openssl s_client -connect your_domain.com:443 -cipher ALL
      
      Or, more targeted:
      openssl s_client -connect your_domain.com:443 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384
      
      On the client-side, you might need to specify a cipher suite if your client is old or has very restrictive defaults. For curl:
      curl -v --ciphers ECDHE-RSA-AES256-GCM-SHA384 https://your_domain.com
      
    • Fix: Update your server’s ssl_ciphers directive to include more modern and widely supported cipher suites. Ensure you’re not excluding all common ones. A good starting point for Nginx/Apache is a modern, recommended list that includes AES-GCM and ECDHE, such as:
      ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256
      
      Restart your web server after changing the configuration. This works because by adding common, strong cipher suites, you increase the probability that the client and server will find at least one mutually supported algorithm to use for encryption.
  2. Incompatible TLS/SSL Protocol Versions: The client and server are trying to use different versions of the TLS/SSL protocol (e.g., client wants TLS 1.3, server only supports TLS 1.2 or older).

    • Diagnosis: Check your server’s SSL configuration for directives like ssl_protocols (Nginx) or SSLProtocol (Apache).
      # Example Nginx ssl_protocols directive
      ssl_protocols TLSv1.2 TLSv1.3;
      
      You can test supported protocols with openssl s_client:
      openssl s_client -connect your_domain.com:443 -tls1
      openssl s_client -connect your_domain.com:443 -tls1_1
      openssl s_client -connect your_domain.com:443 -tls1_2
      openssl s_client -connect your_domain.com:443 -tls1_3
      
      For curl, you can force a protocol version:
      curl -v --tlsv1.2 https://your_domain.com
      curl -v --tlsv1.3 https://your_domain.com
      
    • Fix: Configure your server to support a range of protocols that are both secure and widely compatible. For most modern deployments, enabling TLS 1.2 and TLS 1.3 is sufficient.
      ssl_protocols TLSv1.2 TLSv1.3;
      
      Restart your web server. This works because by enabling specific protocol versions, you ensure that the client has a viable option to connect using a secure and understood version of the protocol.
  3. Expired or Invalid Server Certificate: The server’s SSL certificate has expired, or it’s not trusted by the client’s operating system or browser.

    • Diagnosis:
      • Browser: Look at the certificate details in your browser. Most browsers will explicitly warn you about expired certificates.
      • openssl:
        openssl x509 -in your_certificate.crt -noout -dates
        
        This will show the notBefore and notAfter dates.
      • curl:
        curl -v https://your_domain.com
        
        Look for output related to certificate verification.
    • Fix: Renew your SSL certificate. If you’re using a service like Let’s Encrypt, ensure your renewal process is working correctly. If you’re using a commercial certificate, purchase a new one before the old one expires. Install the new certificate and its intermediate chain correctly on your server. This works because the handshake requires a valid, trusted certificate from the server; an expired or untrusted one immediately breaks the trust establishment phase.
  4. Incorrect Certificate Chain: The server is not sending the full certificate chain (intermediate certificates) needed for the client to verify the server’s certificate against a trusted root CA.

    • Diagnosis: Use online SSL checkers like SSL Labs’ SSL Test (https://www.ssllabs.com/ssltest/) or openssl s_client:
      openssl s_client -connect your_domain.com:443 -showcerts
      
      Examine the output. If you see only one certificate (the server’s end-entity certificate) and not the intermediate(s) leading to a known CA, this is the problem.
    • Fix: Concatenate your server certificate with any required intermediate certificates in the correct order. The server certificate should be first, followed by its intermediate(s). For Nginx, this is typically done in a single file specified by ssl_certificate:
      # In your ssl_certificate file:
      -----BEGIN CERTIFICATE-----
      ... your server certificate ...
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      ... your intermediate certificate 1 ...
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      ... your intermediate certificate 2 (if any) ...
      -----END CERTIFICATE-----
      
      Restart your web server. This works because clients need the full chain to trace the server’s certificate back to a root certificate authority (CA) that they inherently trust; without the intermediates, the verification path is broken.
  5. Client-Side Firewall or Proxy Interference: A firewall or proxy between the client and server is inspecting or blocking SSL traffic, or it’s presenting its own untrusted certificate.

    • Diagnosis: Try connecting from a different network or machine. If it works, the issue is likely local to your network. Check proxy settings on the client. If you’re behind a corporate firewall, it might be performing SSL inspection.
    • Fix: If a proxy is involved, ensure its SSL/TLS configuration is compatible or bypass it for the connection. If a firewall is performing SSL inspection, you may need to configure an exception for the specific domain or IP address, or ensure the firewall’s root certificate is trusted by the client. This works because the handshake might be intercepted and terminated by an intermediary device, or the intermediary might be presenting a certificate that the client doesn’t trust, causing the handshake to fail.
  6. Server Configuration Issues (e.g., ssl_session_tickets or ssl_session_cache): Less common, but misconfiguration of SSL session resumption can sometimes lead to handshake failures, especially after server restarts or in load-balanced environments.

    • Diagnosis: Temporarily disable session resumption features on the server (e.g., ssl_session_tickets off; in Nginx) and see if the handshake succeeds.
    • Fix: Re-enable session resumption with a correctly configured cache or ticket key management system. Ensure session ticket keys are shared across all servers in a load-balanced setup if using ssl_session_tickets. This works because while session resumption speeds up connections, improper handling of session data can lead to state inconsistencies that break subsequent handshakes.

After fixing these, the next most likely error you’ll encounter is an SSL Alert Number 10: No shared cipher, if you’ve only partially resolved the cipher suite issue and the client/server still can’t find a common ground, or potentially a Certificate Unknown error if there’s an issue with certificate authority trust.

Want structured learning?

Take the full Tls-ssl course →