Skip to content

How to Debug a TLS Handshake

Key idea:

TLS handshake failures are among the hardest debug categories. Tools: openssl s_client for shell, Wireshark with TLS decryption for deep analysis, curl -v for application-level. Main signals: ALPN mismatch (HTTP/2 vs 1.1), SNI missing, incomplete cert chain, no cipher overlap, TLS version downgrade.

Below: step-by-step, working examples, common pitfalls, FAQ.

Step-by-Step Setup

  1. Quick probe: openssl s_client -connect example.com:443 -servername example.com -showcerts
  2. Check ALPN: openssl s_client -alpn h2,http/1.1 -connect example.com:443
  3. Check TLS versions: openssl s_client -tls1_3 -connect example.com:443, -tls1_2, -tls1
  4. Check a specific cipher: openssl s_client -cipher ECDHE-RSA-AES128-GCM-SHA256 -connect example.com:443
  5. Network-level with Wireshark: capture tcp port 443, use "(pre)-Master-Secret log" to decrypt
  6. Application-level: curl -v https://example.com 2>&1 | grep -E "SSL|TLS|ALPN"
  7. Overall assessment: Enterno SSL checker — grade + full chain + issues

Working Examples

ScenarioConfig
Basic handshake probeopenssl s_client -connect example.com:443 -servername example.com </dev/null 2>&1 | grep -E "Protocol|Cipher"
ALPN negotiationopenssl s_client -alpn h2 -connect example.com:443 </dev/null | grep -i alpn
Test TLS 1.3openssl s_client -tls1_3 -connect example.com:443 </dev/null
Wireshark filtertcp.port == 443 and tls.record.content_type == 22 # handshake records
curl with cipherscurl -v --tls13-ciphers TLS_AES_128_GCM_SHA256 https://example.com 2>&1 | grep "SSL connection"

Common Pitfalls

  • Without -servername openssl skips SNI → server sends default cert, not yours
  • Wireshark without TLS keys can't decrypt payload (metadata visible)
  • curl CURLOPT_VERBOSE on PHP skips TLS handshake detail, only application
  • Session tickets cache and replay a successful handshake — use -no_ticket for debug
  • Corporate proxy with TLS inspection alters the handshake result — test outside proxy
CertificateExpiry, issuer, domains (SAN)
ChainIntermediate and root CA validation
TLS ProtocolTLS version and cipher suite
VulnerabilitiesHeartbleed, POODLE, weak ciphers

Why teams trust us

TLS 1.3
supported
Full
CA chain check
<2s
result
30/14/7
days-to-expiry alerts

How it works

1

Enter domain

2

TLS chain verified

3

Expiry date & vulnerabilities

What Does the SSL Check Cover?

SSL/TLS is the encryption protocol that protects data between the browser and server. Our tool analyzes the certificate, chain of trust, TLS version, and knownvulnerabilities.

Certificate Details

Issuer, validity period, signature algorithm, covered domains (SAN), and validation type (DV/OV/EV).

Chain of Trust

Full chain verification: from leaf certificate through intermediates to root CA.

TLS Analysis

Protocol version (TLS 1.2/1.3), cipher suites, Perfect Forward Secrecy (PFS) support.

Expiry Alerts

Set up a monitor — get Telegram and email alerts 30/14/7 days before expiration.

DV vs OV vs EV Certificates

DV (Domain Validation)
  • Confirms domain ownership only
  • Issued in minutes automatically
  • Free via Let's Encrypt
  • Suitable for most websites
  • Most common certificate type
OV / EV
  • Organization (OV) or Extended Validation (EV)
  • Issued in 1-5 business days
  • Costs $50 to $500/year
  • For finance, e-commerce, government sites
  • Increases user trust

Who uses this

DevOps

SSL certificate monitoring

Security

TLS config audit

SEO

HTTPS as ranking factor

E-commerce

customer trust

Common Mistakes

Expired certificateBrowsers block sites with expired SSL. Set up auto-renewal or monitoring.
Incomplete certificate chainWithout intermediate CA, some browsers and bots cannot verify the certificate.
Mixed content on HTTPS siteHTTP resources on an HTTPS page — the browser lock icon disappears, reducing trust.
Using TLS 1.0/1.1Legacy TLS versions have known vulnerabilities. Use TLS 1.2+ or 1.3.
Domain mismatch in certificateThe certificate must cover all site domains, including www and subdomains.

Best Practices

Set up auto-renewalLet's Encrypt + certbot with cron — certificate renews automatically every 60-90 days.
Enable HSTSStrict-Transport-Security header forces browsers to always use HTTPS.
Use TLS 1.3TLS 1.3 is faster (1-RTT handshake) and safer — legacy ciphers removed.
Monitor expiration datesCreate a monitor on Enterno.io — get notified well before expiration.
Verify chain after renewalAfter certificate renewal, confirm that intermediate certificates are installed.

Get more with a free account

SSL certificate monitoring, check history and alerts 30 days before expiry.

Sign up free

Learn more

Frequently Asked Questions

How to decrypt a Wireshark capture?

Run browser with <code>SSLKEYLOGFILE=/tmp/sslkeys.log</code>. In Wireshark → Edit → Preferences → TLS → (Pre)-Master-Secret log → /tmp/sslkeys.log.

openssl shows old cipher — normal?

Yes, server offers in preference order. Negotiated cipher is in the "Cipher: XXX" line.

How to check OCSP stapling?

<code>openssl s_client -status -connect example.com:443 </dev/null 2>&amp;1 | grep "OCSP Response"</code>. Should be "OCSP Response Status: successful".

How to see TLS version in browser?

DevTools → Security tab → Connection. Or <code>chrome://net-internals/#ssl</code>.