How To Guide

How to Fix SSL Certificate Errors: Complete Diagnostic Guide

Diagnose and fix common SSL/TLS errors including expired certs, hostname mismatch, missing intermediates, CAA blocks, and Let's Encrypt rate limits.

How to Fix SSL Certificate Errors

An SSL/TLS error means the browser rejected the certificate your server presented. The fix depends entirely on which validation step failed. This guide walks through the seven most common failures, the browser error strings they produce, and the exact commands to diagnose and repair each one.

Start with a diagnostic snapshot

Before changing anything, capture what the server is actually serving:

openssl s_client -connect example.com:443 -servername example.com -showcerts < /dev/null

The -servername flag sends the SNI extension so virtual-hosted sites return the correct certificate. Look at the Verify return code at the bottom and the Certificate chain block at the top. Then decode the leaf:

openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null \
  | openssl x509 -text -noout

The Subject, Issuer, Validity block, and X509v3 Subject Alternative Name extension answer most questions immediately.

NET::ERR_CERT_AUTHORITY_INVALID

What it means: The browser cannot chain the leaf certificate up to a trusted root. The issuer is either an unknown CA, a self-signed certificate, or (most commonly) a public CA whose intermediate certificate was not sent by the server.

How to fix: First distinguish the sub-cases. Run openssl x509 -text -noout on the leaf and read the Issuer line. If Issuer equals Subject, the certificate is self-signed and must be replaced with one from a public CA (Let's Encrypt, ZeroSSL, DigiCert). If Issuer is a real CA, the problem is almost always a missing intermediate, covered below.

Incomplete chain (missing intermediate)

What it means: Browsers only trust roots. The server must send the leaf plus every intermediate that links leaf->root. Servers that only send the leaf produce NET::ERR_CERT_AUTHORITY_INVALID on Firefox and mobile browsers even when Chrome silently repairs it via AIA fetching.

How to fix: Confirm the depth in the s_client output. You should see 0 s:CN=example.com and 1 s:CN=... i:CN=ISRG Root .... If only depth 0 appears, concatenate the intermediate PEM to your certificate file (fullchain.pem from certbot already does this) and reload nginx or Apache. Test with:

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt fullchain.pem

NET::ERR_CERT_DATE_INVALID and expired certificates

What it means: The current time is outside the Not Before / Not After window. Almost always this is expiry; occasionally it is a server whose clock is wrong.

How to fix: Confirm expiry:

openssl x509 -in cert.pem -noout -dates

For Let's Encrypt run certbot renew then reload the webserver. If Not After is in the future but the browser still complains, check the server clock with timedatectl and enable NTP.

Self-signed certificate warnings

What it means: The certificate's Issuer is itself. Fine for internal tooling, never acceptable for public sites.

How to fix: Replace with a publicly-issued certificate. For a quick free option install certbot and run certbot --nginx -d example.com. For internal-only hosts, distribute your private root to client trust stores instead of clicking through the warning.

Hostname mismatch (SAN)

What it means: Modern browsers ignore the Common Name entirely and validate the hostname against the Subject Alternative Name extension. A certificate issued for example.com is not valid for www.example.com unless both appear in the SAN list.

How to fix: Inspect the SAN block:

openssl x509 -in cert.pem -text -noout | grep -A1 "Subject Alternative Name"

Reissue including every hostname the site uses. With certbot: certbot certonly -d example.com -d www.example.com -d api.example.com.

CAA record blocking issuance

What it means: Certification Authority Authorization (RFC 8659) is a DNS record that whitelists which CAs may issue for your domain. If your CAA record lists digicert.com and you try to issue from Let's Encrypt, the CA must refuse. The error surfaces in your ACME client, not in the browser.

How to fix: Inspect and correct the record:

dig CAA example.com +short

Add an entry for your target CA, for example 0 issue "letsencrypt.org", or remove the restrictive record. DNS propagation is checked at issuance time, so retry after TTL expires.

Let's Encrypt rate limits

What it means: Let's Encrypt caps certificates per registered domain to 50 per week, duplicate certificates to 5 per week, and failed validations to 5 per hostname per hour. Hitting these produces too many certificates already issued or too many failed authorizations from certbot.

How to fix: Do not loop certbot. Switch to the staging environment while debugging: certbot --staging .... Staging has vastly higher limits and issues untrusted certificates you can inspect. Once configuration is clean, run once against production. Duplicate limits reset after seven days; failed-validation limits reset hourly.

Final verification

After any fix, rerun s_client and require a clean result:

openssl s_client -connect example.com:443 -servername example.com -verify_return_error < /dev/null

Expect Verify return code: 0 (ok). Then open the site in a fresh browser profile so cached error pages do not mislead you.

ssl certificate error NET::ERR_CERT_AUTHORITY_INVALID NET::ERR_CERT_DATE_INVALID openssl s_client certificate chain hostname mismatch letsencrypt rate limit CAA record

Explore 300+ Free Tools

Utilko has tools for developers, writers, designers, students, and everyday users — all free, all browser-based.