Why HTTPS Certificate Errors Occur
Visitors attempting to reach a website encounter a red security barrier stating "Your connection is not private" with error codes such as NET::ERR_CERT_COMMON_NAME_INVALID, SEC_ERROR_EXPIRED_CERTIFICATE, or ERR_CERT_AUTHORITY_INVALID. In many cases, mobile devices or curl commands fail while the desktop browser loads the site fine due to a missing intermediate certificate.
NET::ERR_CERT_COMMON_NAME_INVALID or NET::ERR_CERT_AUTHORITY_INVALID or SEC_ERROR_UNKNOWN_ISSUER.Why does Why HTTPS Certificate Errors Occur occur?
Primary Root Cause
During the TLS handshake, the server presents an X.509 certificate to prove identity. The client validates: (1) Is the current date within the NotBefore/NotAfter validity window? (2) Does the hostname match the SAN extension? (3) Is the signature chain unbroken all the way to a trusted Root CA? (4) Has the certificate been revoked via CRL or OCSP? If any check fails, the browser aborts the connection.
A very common failure mode is "incomplete certificate chain". Web servers configured with `cert.pem` instead of `fullchain.pem` omit the intermediate CA certificate. Desktop browsers often cache intermediate certificates from previous browsing sessions or use AIA (Authority Information Access) fetching, masking the error. Mobile browsers, curl, and backend microservices do not, crashing with `SEC_ERROR_UNKNOWN_ISSUER`.
How to Confirm You Are Facing This Exact Issue
Chrome displays "Your connection is not private" with NET::ERR_CERT_AUTHORITY_INVALID.
Curl command returns "curl: (60) SSL certificate problem: unable to get local issuer certificate".
The website works at https://www.example.com but throws an error at https://example.com.
Mobile apps or iOS Safari refuse to connect, while desktop Chrome opens the site.
Explicit Diagnostic Reasoning
Pinpoint the exact failure cause using browser error codes and OpenSSL inspection:
"If the error code is NET::ERR_CERT_DATE_INVALID or SEC_ERROR_EXPIRED_CERTIFICATE"
The certificate expired past its NotAfter timestamp, or your client device has an inaccurate system clock.
→ Check your computer’s clock, then check your server’s auto-renewal cronjob (certbot renew).
"If the error code is NET::ERR_CERT_COMMON_NAME_INVALID"
The domain in the browser address bar is not listed in the certificate’s Subject Alternative Names (SAN).
→ Reissue the certificate to include both example.com and *.example.com or www.example.com.
"If the site loads in desktop Chrome but fails in curl, Python requests, or mobile Safari"
Your web server is missing the intermediate CA certificate (incomplete certificate chain).
→ Configure your web server to serve "fullchain.pem" instead of "cert.pem".
"If the error code is NET::ERR_CERT_AUTHORITY_INVALID"
The certificate was issued by an untrusted or self-signed Certificate Authority.
→ Replace the self-signed certificate with one issued by a trusted public CA like Let’s Encrypt.
Inspects the full certificate chain returned by the server, verifying depth and issuer signatures.
Long-Term Engineering Solution
Install a properly issued certificate from an automated ACME provider (Let’s Encrypt, ZeroSSL, Cloudflare), bundle the intermediate CA chain, and automate 60-day renewals.
Architectural Pattern
Always use ACME protocols with certbot or Caddy/Traefik for automated certificate lifecycle management, and configure `fullchain.pem` to prevent broken intermediate trust chains.
How do you fix this step-by-step?
Inspect Certificate Details with OpenSSL
Run OpenSSL to read the validity dates, Subject Alternative Names, and issuer.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -subject -ext subjectAltNameBundle the Full Certificate Chain
Update your Nginx or Apache configuration to point to fullchain.pem (which contains your server certificate plus the intermediate CA certificate).
# Nginx - CORRECT CONFIGURATION
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 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;
}Include All Domains in SAN List
When obtaining a certificate via Certbot, request all required hostnames in a single certificate.
# Request multi-domain certificate including apex and www
certbot --nginx -d example.com -d www.example.com -d api.example.comAutomate and Test Certificate Renewal
Ensure the systemd timer or cron job is active and dry-run renewals to avoid surprise expiration.
# Test automatic renewal dry run
sudo certbot renew --dry-run
# Check certbot timer status on systemd
systemctl status certbot.timerWhat are common misconceptions and mistakes when fixing this?
Using cert.pem instead of fullchain.pem in Nginx.
Perché fallisce: `cert.pem` only contains the leaf certificate. Without the intermediate CA certificate, non-browser clients (curl, mobile apps, payment webhooks) cannot trace trust to the root CA and abort the connection.
✓ Alternativa corretta: Always configure `ssl_certificate` with `fullchain.pem`.
Issuing a certificate for "www.example.com" and forgetting the apex "example.com".
Perché fallisce: Users typing "example.com" receive NET::ERR_CERT_COMMON_NAME_INVALID before any HTTP-to-HTTPS or www-redirect can execute.
✓ Alternativa corretta: Always issue multi-domain SAN certificates covering both `example.com` and `www.example.com`.
Wildcard certificates (*.example.com) covering the apex domain.
Perché fallisce: According to RFC 6125, `*.example.com` matches `sub.example.com` and `api.example.com`, but does NOT match the root apex `example.com` or multi-level subdomains `a.b.example.com`.
✓ Alternativa corretta: Explicitly request both `example.com` and `*.example.com` when generating wildcard certificates.
Can this fix introduce security vulnerabilities?
Certificate errors protect users from active Man-in-the-Middle (MitM) attacks, DNS spoofing, and malicious traffic interception.
Security Risks If Ignored
- •Man-in-the-Middle Interception: If users bypass certificate warnings, attackers can decrypt credentials and sensitive traffic.
- •HSTS Hard Lockout: If a site enforces HSTS, browsers disable the "Proceed anyway" button, completely blocking access when a cert expires.
- •Compromised Private Keys: Using outdated weak keys (RSA 1024) or exposing keys in version control permits offline decryption.
Hardening Best Practices
- ✓Use modern elliptic curve cryptography (ECDSA P-256) or RSA 2048/4096-bit keys.
- ✓Monitor certificate expiration using automated alerts at 30, 14, and 7 days prior.
- ✓Never instruct end users to click "Proceed to unsafe website" or use insecure flags like `curl -k`.
Comparing Incomplete vs Complete TLS Handshake Chains
Certificate Chain from Server (INCOMPLETE):
0 s:CN = example.com
i:C = US, O = Let's Encrypt, CN = R3
<-- MISSING INTERMEDIATE CA CERTIFICATE (R3 -> ISRG Root X1)
Result in curl / Python / Mobile:
curl: (60) SSL certificate problem: unable to get local issuer certificateCertificate Chain from Server (COMPLETE / FULLCHAIN):
0 s:CN = example.com
i:C = US, O = Let's Encrypt, CN = R3
1 s:C = US, O = Let's Encrypt, CN = R3
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
Result:
SSL certificate verify ok. Handshake complete (TLS 1.3).Frequently Asked Questions About Why HTTPS Certificate Errors Occur
Why does my SSL certificate work on my laptop but fail on my phone or curl?↓
Your web server is missing the intermediate CA certificate. Desktop browsers cache intermediate certificates from prior visits, while mobile devices and curl do not.
This is the classic "missing intermediate certificate" issue. To fix it, change your web server configuration from `cert.pem` to `fullchain.pem` so the server sends both the leaf and intermediate certificates.
Can I use a wildcard certificate for all subdomains including sub.sub.example.com?↓
No. A wildcard certificate (*.example.com) only covers one single subdomain level. It will not cover multi-level subdomains or the root domain.
A certificate for `*.example.com` matches `app.example.com` and `blog.example.com`. It will NOT match `dev.app.example.com` or `example.com`. For nested subdomains, you must request specific SANs or separate wildcards.
Why do browsers prevent bypassing HTTPS errors on some websites?↓
When a website deploys HSTS (HTTP Strict Transport Security), the browser strictly prohibits the user from bypassing certificate errors or clicking "Proceed anyway".
HSTS guarantees that the browser will only accept a 100% valid, untampered TLS connection. If any certificate error occurs on an HSTS-enabled domain, the browser treats it as an active attack and kills the session immediately.