Debugging & Troubleshooting

TLS/SSL Certificate Troubleshooting Guide

How to diagnose and fix SSL/TLS certificate errors — expired certificates, chain issues, mixed content, and cipher mismatches.

Common SSL/TLS Error Messages

  • NET::ERR_CERT_DATE_INVALID — Certificate has expired
  • NET::ERR_CERT_AUTHORITY_INVALID — Self-signed or untrusted CA
  • NET::ERR_CERT_COMMON_NAME_INVALID — Domain name mismatch
  • SSL_ERROR_HANDSHAKE_FAILURE_ALERT — Protocol or cipher mismatch

Diagnosing with OpenSSL

OpenSSL is the primary tool for debugging certificate issues:

Check Certificate Details

# View certificate info
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
  openssl x509 -noout -dates -subject -issuer

# Check expiration date
echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -enddate

Verify Certificate Chain

# Show full chain
openssl s_client -connect example.com:443 -showcerts </dev/null

# Verify chain against system CA store
openssl s_client -connect example.com:443 -verify_return_error </dev/null

Issue 1: Expired Certificate

The most common issue. Certificates typically expire after 90 days (Let's Encrypt) or 1 year (commercial CAs).

Fix:

  • Set up automatic renewal with certbot or your CA's tools
  • Monitor certificate expiry with alerting (at 30, 14, 7 days)
  • After renewal, restart/reload your web server

Issue 2: Incomplete Certificate Chain

The server sends its own certificate but not the intermediate CA certificates. Some browsers can fetch missing intermediates, others (mobile, curl) cannot.

Fix: Configure your server to send the full chain:

# Nginx: use fullchain.pem, not cert.pem
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Issue 3: Domain Name Mismatch

The certificate's Common Name (CN) or Subject Alternative Names (SANs) don't match the domain being accessed.

Fix: Ensure the certificate covers all domains:

# Check which domains the cert covers
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
  openssl x509 -noout -ext subjectAltName

Issue 4: Mixed Content

The page loads over HTTPS but includes HTTP resources (images, scripts). Browsers block or warn about these.

Fix: Use relative URLs or // protocol-relative URLs. Better yet, serve everything over HTTPS and add Content-Security-Policy: upgrade-insecure-requests.

Prevention

  • Automate certificate renewal (certbot, ACME)
  • Use HSTS to prevent HTTP downgrade
  • Monitor with tools like SSL Labs (ssllabs.com/ssltest)
  • Test with curl -v after every certificate change

Related Protocols

Related Glossary Terms

More in Debugging & Troubleshooting