SSL Certificate Errors Explained: Expired, Mismatch, Mixed Content
You click your own site and the browser throws up a red warning instead of the padlock. Or a customer emails you a screenshot that just says "your site isn't safe." SSL errors all get lumped together as "the SSL is broken," but Chrome, Firefox, and Safari actually tell you exactly what's wrong if you read the error code instead of just the scary red screen. Here's how to decode it and fix the right thing the first time.
Symptom: Which Error Are You Actually Seeing?
Before touching anything, click "Advanced" on the warning page and copy the exact error code. It matters — each one points to a different root cause, and guessing wrong wastes an hour re-issuing a certificate that was never the problem.
NET::ERR_CERT_DATE_INVALID— the certificate has expired or your system clock is wrong.NET::ERR_CERT_COMMON_NAME_INVALID— the certificate doesn't match the domain you're visiting.NET::ERR_CERT_AUTHORITY_INVALID— the certificate isn't signed by a trusted authority, or the chain is broken.SEC_ERROR_UNKNOWN_ISSUER(Firefox) — same family as the one above.- Padlock shows but with a warning triangle, or "Connection is not fully secure" — mixed content, not a certificate problem at all.
Expired Certificate: NET::ERR_CERT_DATE_INVALID
This is the most common one, and it's rarely as simple as "the cert expired." Two different things trigger this exact error:
- The certificate genuinely expired — auto-renewal (AutoSSL, Certbot, ACME) silently failed a few cycles back and nobody noticed.
- The certificate is fine, but the visitor's device clock is wrong. This happens a lot on older phones, VMs that lost NTP sync, or a laptop that's been asleep for weeks.
Check the actual expiry from the command line instead of trusting the browser:
echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates
That gives you notBefore and notAfter in UTC. If notAfter is in the past, the cert is genuinely dead — reissue it. If it's still valid, the problem is almost always the client's clock; ask the person reporting it to check their system date and time settings.
If you're on Getwebup cPanel hosting and AutoSSL keeps failing to renew silently, that's usually a DCV or CAA record issue rather than the certificate itself — that's a separate rabbit hole worth checking in cPanel's SSL/TLS Status page before you manually reissue anything.
Domain Mismatch: NET::ERR_CERT_COMMON_NAME_INVALID
The certificate is valid and trusted, but it was issued for a different hostname than the one in the address bar. The usual culprits:
- You have a cert for
example.combut no SAN entry forwww.example.com(or vice versa). - A staging or dev subdomain (
staging.example.com) is sharing a server IP with a site that has its own certificate, and the web server is serving the wrong one by default. - You recently added an addon domain or subdomain in cPanel and the certificate hasn't caught up yet — AutoSSL runs on a schedule, it doesn't fire instantly on domain creation.
List every hostname actually covered by the cert:
echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
If the domain you're visiting isn't in that list, the fix is to reissue the certificate with the correct SAN entries — in cPanel, run AutoSSL manually for that domain (SSL/TLS Status > select domain > Run AutoSSL), or on a VPS with Certbot, add the missing hostname with -d flags and rerun the issuance.
Untrusted Certificate: NET::ERR_CERT_AUTHORITY_INVALID
This one means the browser doesn't trust whoever signed the certificate. Two common causes:
1. It's actually self-signed
Common on fresh VPS installs where Apache or Nginx shipped with a default self-signed cert, or a staging environment nobody swapped for a real one. Self-signed certs will always throw this error in a normal browser — there's no fix except replacing it with one from a trusted CA (Let's Encrypt is free and works fine for this).
2. The intermediate chain is incomplete
Your certificate is real and CA-issued, but the server isn't sending the intermediate certificate along with it, so the browser can't build a trust path back to a root it recognizes. This is sneaky because some browsers cache intermediates and show the site as fine, while others (and most command-line tools) fail. Test it properly with SSL Labs or:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com | grep -i "Verify return code"
Anything other than Verify return code: 0 (ok) means the chain is broken. Fix: reinstall the full certificate chain (not just the leaf cert) through your hosting panel's SSL installer, or if you're managing Nginx/Apache manually, make sure the ssl_certificate directive points at the fullchain file, not just the domain cert.
"Not Fully Secure" — Mixed Content
The certificate is completely fine here. The padlock shows a warning because the page is loading some resources — images, scripts, stylesheets, an embedded font — over plain http:// instead of https://. Browsers block or flag this because an attacker on the network could tamper with that one insecure resource even though the page itself is encrypted.
Open DevTools (F12) > Console tab and reload the page. Mixed content warnings list the exact insecure URLs. On WordPress, this is almost always old http:// links baked into the database from before you enabled HTTPS — a plain find-and-replace in wp_options, post content, and widget settings clears it, or use WP-CLI:
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables
Back up the database before running that — search-replace touches every table and there's no undo.
Quick Reference Table
| Error | Root Cause | Fastest Check |
|---|---|---|
| ERR_CERT_DATE_INVALID | Expired cert or wrong client clock | openssl x509 -noout -dates |
| ERR_CERT_COMMON_NAME_INVALID | Domain not in the certificate's SAN list | openssl x509 -noout -text |
| ERR_CERT_AUTHORITY_INVALID | Self-signed cert or broken chain | SSL Labs test or Verify return code |
| "Not fully secure" | Mixed HTTP/HTTPS content | DevTools Console warnings |
Prevention: Stop Getting Paged for This
- Set a calendar reminder or monitoring check for certificate expiry — don't rely on auto-renewal silently working forever.
- After issuing or renewing any certificate, run it through SSL Labs' test once. It catches chain issues immediately that a browser might mask.
- When adding a new subdomain or addon domain, run AutoSSL (or Certbot) manually right away instead of waiting for the next scheduled pass.
- Force HTTPS site-wide with a redirect and an HSTS header once everything's clean, so mixed content and downgrade issues become obvious fast instead of quietly recurring.
Most SSL errors trace back to one of these four, and the fix is almost always faster than the panic the red warning page induces. Read the code, run one openssl command, and you'll usually know exactly what to do within a couple of minutes.
Frequently asked questions
Why does my SSL certificate show as valid in cPanel but the browser still blocks the site?
cPanel checks that a certificate exists and hasn't expired, but browsers also verify the certificate chain and that the hostname matches exactly. A missing intermediate certificate or a domain not covered by the SAN list will pass cPanel's check but still fail in the browser.
Can a wrong system clock really cause an SSL error?
Yes. If a device's date or time is off by even a day, certificate validation fails because the current time falls outside the certificate's valid range. This produces the exact same NET::ERR_CERT_DATE_INVALID error as a genuinely expired certificate.
Do I need to pay for an SSL certificate to fix these errors?
No. Let's Encrypt issues free, browser-trusted certificates and covers the vast majority of these fixes. Paid certificates only matter for specific cases like extended validation branding or certain enterprise compliance requirements.
Why do I only see the mixed content warning on some pages of my site?
Mixed content is caused by individual resources loaded over http:// on that specific page - an old image URL, an embedded video, a third-party widget. Other pages that don't reference those particular assets won't trigger the warning.
How long does it take for a new SSL certificate to work after I reissue it?
Usually within a few minutes on the server side, but browsers and some CDNs cache the old certificate. Clear your browser cache or test in an incognito window if the warning persists after reissuing.