Common SSL/TLS Error Messages
NET::ERR_CERT_DATE_INVALID— Certificate has expiredNET::ERR_CERT_AUTHORITY_INVALID— Self-signed or untrusted CANET::ERR_CERT_COMMON_NAME_INVALID— Domain name mismatchSSL_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 -vafter every certificate change