Overview
SSL/TLS issues fall into 7 main categories. Start by identifying your symptom, then follow the decision tree to find the cause and fix.
Browser Warning
Can't Connect
Name Error
Chain Issues
Cipher Error
Code Fails
Random Failures
Browser Warnings
Common Causes
- ERR_CERT_DATE_INVALID: Certificate expired - renew it
- ERR_CERT_AUTHORITY_INVALID: Untrusted CA - use public CA or install root
- ERR_CERT_COMMON_NAME_INVALID: Domain mismatch - get correct certificate
- ERR_CERT_REVOKED: Certificate revoked - obtain new one
- "Not Secure": HTTP only or mixed content
Connection Failures
Diagnose by Error Type
- Connection refused (instant): Service not running or wrong port
- Timeout (waits then fails): Firewall blocking port 443
- Handshake failed: TLS version or cipher mismatch
- Connection reset: Server rejecting client or application error
# Check if port 443 is open nc -zv example.com 443 # Test TLS connection openssl s_client -connect example.com:443
Name Mismatch Errors
Common Scenarios
- Wrong certificate installed: Check SNI config, verify correct cert file
- Subdomain not covered: Need SAN entry or wildcard
- Wildcard depth limit: *.example.com doesn't cover a.b.example.com
- Root domain missing: *.example.com doesn't cover example.com
- Accessing by IP: Certificate only contains hostnames
# Check what names are in the certificate openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
Certificate Chain Issues
Trust Path Problems
- "Unable to get local issuer": Missing intermediate certificate
- "Self-signed in chain": Private CA not trusted
- "PKIX path building failed": Java truststore issue
- Works in browser, fails in curl: Server not sending full chain
Solution: Concatenate leaf + intermediate(s) into fullchain.crt and configure server to use it.
# Check how many certs server sends openssl s_client -connect example.com:443 -showcerts 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
Cipher/Protocol Errors
Negotiation Failures
- "No cipher overlap": Client and server have no common ciphers
- "Protocol not supported": TLS version mismatch (often legacy TLS disabled)
- "DH key too small": Weak DH parameters, generate new 2048-bit params
# Test specific TLS version openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3 # List server ciphers nmap --script ssl-enum-ciphers -p 443 example.com
Code Failures (Browser Works)
By Language/Tool
- curl: CA bundle issue - update ca-certificates or specify --cacert
- Python: Update certifi package or specify verify="/path/to/ca.crt"
- Java: Update cacerts or import CA with keytool
- Node.js: Set NODE_EXTRA_CA_CERTS for missing intermediates
Never in Production
Never use verify=False (Python), rejectUnauthorized: false (Node), or -k (curl) in production. Fix the underlying issue instead.
Intermittent Failures
Pattern-Based Diagnosis
- Random failures: Check for inconsistent certs across load balancer backends
- Works then fails: Certificate rotation during long connections
- Location-dependent: Corporate SSL inspection or DNS inconsistency
- CDN issues: Stale certificates on edge servers - purge cache
Essential Debug Commands
View full certificate
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text
Check expiry date
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate
Show full chain
openssl s_client -connect example.com:443 -showcerts
Verbose curl
curl -v https://example.com
Related Resources
Certificate Error Decoder
Decode browser error codes for quick diagnosis
Failure Scenarios Guide
Comprehensive guide to all certificate failure types
Chain Builder Guide
Fix certificate chain issues step by step
OpenSSL s_client
Advanced SSL/TLS debugging with OpenSSL
How TLS Works
Understand the TLS protocol for better debugging
