Nginx

How to Fix Nginx SSL Certificate net::ERR_CERT_COMMON_NAME_INVALID After Certbot Run

4 min read by DebuggedIt

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.com alone doesn't automatically cover app.yourdomain.com or www.yourdomain.com, since these are all considered distinct hostnames unless explicitly included.
  • Multiple server blocks in Nginx's configuration overlap or aren't specific enough, causing Nginx to select the wrong certificate for a given server_name via SNI matching β€” a default or catch-all server block 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.