SSL/TLS Error
Security - Certificate validation failed
SSL/TLS Certificate Errors
Common SSL Errors
ERR_CERT_DATE_INVALID
Certificate has expired or is not yet valid
ERR_CERT_AUTHORITY_INVALID
Certificate not signed by a trusted CA (self-signed)
ERR_CERT_COMMON_NAME_INVALID
Certificate doesn't match the domain name
SSL_ERROR_HANDSHAKE_FAILURE_ALERT
TLS version or cipher suite mismatch
Diagnosing Certificate Issues
# Check certificate details
openssl s_client -connect example.com:443 -servername example.com
# View certificate info
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -dates -subject -issuer
# Check full certificate chain
openssl s_client -connect example.com:443 -showcerts
# Test specific TLS version
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
Certificate Expired
SSL certificates have a validity period (usually 90 days for Let's Encrypt, 1 year for paid certs). When expired, browsers refuse to connect.
# Check expiry date
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -enddate
# Renew Let's Encrypt certificate
sudo certbot renew
# Force renewal
sudo certbot renew --force-renewal
Hostname Mismatch
The certificate must match the domain being accessed. Check that the certificate covers the exact domain or uses a wildcard.
# Certificate covers:
# - example.com
# - www.example.com
# But NOT:
# - api.example.com (unless using *.example.com wildcard)
# - subdomain.api.example.com (wildcards are single-level)
# Check what names the cert covers
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
Self-Signed Certificates
Self-signed certs aren't trusted by browsers. Use Let's Encrypt for free trusted certificates.
# Install certbot and get a free certificate
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# Or for Apache
sudo certbot --apache -d example.com
# Auto-renewal (add to crontab)
0 12 * * * /usr/bin/certbot renew --quiet
Missing Intermediate Certificate
Browsers need the full certificate chain. Missing intermediates cause errors on some clients.
# Test certificate chain
curl -vvI https://example.com 2>&1 | grep -A 10 "Server certificate"
# Nginx - include full chain
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
TLS Version Issues
| Version | Status |
|---|---|
| TLS 1.3 | Current standard |
| TLS 1.2 | Still secure |
| TLS 1.1 | Deprecated |
| TLS 1.0 | Insecure |
| SSL 3.0 | Insecure |
# Nginx - modern TLS config
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
Quick Fixes
- Expired cert: Renew with
certbot renew - Wrong domain: Reissue cert with correct SANs
- Self-signed: Switch to Let's Encrypt
- Chain incomplete: Use fullchain.pem, not just cert.pem
- Old TLS: Update to TLS 1.2 minimum