How to Fix Nginx SSL Certificate net::ERR_CERT_COMMON_NAME_INVALID After Certbot Run
Quick answer
The browser rejects your site's certificate with a common name mismatch error, even though you just ran Certbot and it reported success. This means the...
The browser rejects your site's certificate with a common name mismatch error, even though you just ran Certbot and it reported success. This means the certificate the browser actually received doesn't cover the domain being requested β usually because Nginx is serving the wrong certificate for that specific hostname, not because Certbot itself failed to issue one correctly.
The Problem
The browser blocks the connection with a clear certificate mismatch warning:
net::ERR_CERT_COMMON_NAME_INVALID
Checking the certificate actually being presented reveals it covers a different domain than the one you're visiting:
$ openssl s_client -connect app.yourdomain.com:443 -servername app.yourdomain.com </dev/null 2>/dev/null | openssl x509 -noout -subject
subject=CN=yourdomain.com
Notice the certificate's subject is yourdomain.com, but you're actually connecting to app.yourdomain.com β a different hostname the certificate doesn't cover.
Why It Happens
Certbot issues certificates for the specific domain(s) you request, and Nginx uses Server Name Indication (SNI) to decide which certificate to present for a given incoming hostname, based on matching server_name directives across your configured server blocks. A mismatch happens when:
- Certbot was run for the wrong domain or missed a subdomain β issuing a certificate for
yourdomain.comalone doesn't automatically coverapp.yourdomain.comorwww.yourdomain.com, since these are all considered distinct hostnames unless explicitly included. - Multiple
serverblocks in Nginx's configuration overlap or aren't specific enough, causing Nginx to select the wrong certificate for a givenserver_namevia SNI matching β a default or catch-allserverblock sometimes ends up matching a hostname it shouldn't. - A wildcard certificate was expected but a single-domain certificate was actually issued, since Certbot's default HTTP-01 challenge doesn't support wildcard certificates β those require the DNS-01 challenge method instead.
- DNS points a subdomain at the same server as the main domain, but no certificate or Nginx configuration was ever set up for that specific subdomain, so it falls through to whatever certificate happens to be configured as the default for that IP/port.
The Fix
First, check exactly which domains your current certificate actually covers:
sudo certbot certificates
Certificate Name: yourdomain.com
Domains: yourdomain.com www.yourdomain.com
Expiry Date: 2026-11-05
If the domain you're trying to serve (like app.yourdomain.com) isn't in this list, reissue the certificate including it explicitly:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com -d app.yourdomain.com
Certbot's --nginx plugin will typically also update your Nginx configuration automatically to reference the new certificate, but it's worth verifying manually that each relevant server block points at the correct certificate files:
server {
listen 443 ssl;
server_name app.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
}
If you need genuinely separate certificates per subdomain rather than one certificate covering multiple names, issue each independently and make sure each server block references its own matching certificate rather than accidentally sharing one meant for a different domain:
sudo certbot --nginx -d app.yourdomain.com
For a wildcard certificate covering any subdomain automatically, use the DNS-01 challenge instead of the default HTTP-01 method, since wildcards require proving domain ownership via a DNS TXT record rather than an HTTP file:
sudo certbot certonly --manual --preferred-challenges dns -d "*.yourdomain.com" -d yourdomain.com
Certbot will prompt you to add a specific TXT record to your DNS before it can issue the wildcard certificate β many DNS providers also have Certbot plugins that automate this step rather than requiring manual TXT record management each renewal.
After any certificate change, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
Still Not Working?
If the certificate now correctly includes the domain but the browser still shows the mismatch, verify Nginx is actually serving the updated certificate for that specific hostname via SNI, rather than an older cached configuration or a competing server block still matching first:
openssl s_client -connect app.yourdomain.com:443 -servername app.yourdomain.com </dev/null 2>/dev/null | openssl x509 -noout -text | grep DNS
DNS:yourdomain.com, DNS:www.yourdomain.com, DNS:app.yourdomain.com
If this now correctly lists the expected domain but the browser still complains, clear the browser's own cached certificate/HSTS state for that domain, since browsers can cache certificate information more aggressively than a simple page reload will clear β test in a private/incognito window or a completely different browser to rule out client-side caching before assuming the server-side fix hasn't taken effect.