NET::ERR_CERT_COMMON_NAME_INVALID When Moving SSL Certs Between Servers

Been doing a lot of spring cleaning lately and every now and then I stumble into walls that send me down rabbit holes. Sucks for me, but it’s great for you. I use this site to document the process for myself, and in the process share some tips for anyone that might need it.


Break the error down and it tells you everything you need to know:

Error Certificate Common Name Invalid -> i.e., the common name on the cert does not match the domain you’re trying to use it on (common name -> domain name for simple terms).

This is telling you that externally the browser is not seeing what you think it should be seeing. This is brought about by a cuople of reasons:

1 – The wrong certificate is installed;

2 – There is a misconfiguration on your server;

Let’s explore these.

Troubleshooting on a VPS / Dedicated machine

Some of these can work on a shared machine, but this is all done assuming you have full access to the machine.

Step 1: Verify Common Name

Verify two things –

  1. The certificate you’re migrating and verify it is for the right domain;
  2. What the browser is seeing remotely;

Verify the certificate you’re uploading using openssl with this command:

openssl x509 -noout -text -in /etc/letsencrypt/live/[domainname]/fullchain.pem  

This will read the certificate and tell you what the common name is. If that is correct, look at what the browser is seeing by using openssl with this command:

openssl s_client -showcerts -connect [domainname]:443

This last one tells you what the browser is seeing, so it should tell you whether the common name is right or wrong.

Step 2: Verify Cert Placement and Vhosts File

The most common mistake boils down to the wrong placement and configuration of a vhosts file. To help, I have uploaded a basic vhosts file that you can use to perform a diff and confirm various elements.

Some of the key things to check for:

  • You’re referencing the right port (i.e., 443) (i.e.,
<VirtualHost *:80> 
  • The path to the certs are correct
SSLCertificateFile /etc/letsencrypt/live/[domainname]/fullchain.pem                                                     SSLCertificateKeyFile /etc/letsencrypt/live/[domainname]/privkey.pem                                                    Include /etc/letsencrypt/options-ssl-apache.conf 
  • The privkey and fullchain files have the right components (I find it much easier to simply scp the files from the old server to their new home on the new server to avoid any potential issues when copying / pasting).

Verify your Vhosts file is free of errors by running this:

# apachectl configtest
Step 3: Verify Vhosts with HTTPS is Enabled

You cannot forget to verify if the new vhosts is enabled. This simple step can cause a lot of heartburn, trust me.

A very simple way to verify what is enabled is to use this:

# apache2ctl -S 

If you don’t see your domain, that’s a problem. If you see your domain, but notice the port is not 443, that is a problem.

The tips above should get close to helping resolve this error. I can’t stress the importance of Step 1, verifying what your cert is for, and what the browser is seeing goes a long way to telling you where the problem really is.

Random Tip Using cURL

There are other tools that can be extremely helpful when troubleshooting these problems, one of those is cURL.

Here is an example of a cURL command you can run that is extremely helpful in a scenario like this:

$ curl -vvv "" | more

The output will give you something like this:

Trying [IP Address]:443...        
* TCP_NODELAY set                                                                                                    * Connected to ([IP Address]) port 443 (#0)                                                           * ALPN, offering h2                                                                                                  * ALPN, offering http/1.1                                                                                            * successfully set certificate verify locations:                                                                     *   CAfile: /etc/ssl/certs/ca-certificates.crt                                                                         CApath: /etc/ssl/certs                                                                                             } [5 bytes data]                                                                                                     * TLSv1.3 (OUT), TLS handshake, Client hello (1):                                                                    } [512 bytes data]                                                                                                   * TLSv1.3 (IN), TLS handshake, Server hello (2):                                                                     { [122 bytes data]                                                                                                   * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):                                                             { [25 bytes data]                                                                                                    * TLSv1.3 (IN), TLS handshake, Certificate (11):                                                                     { [4024 bytes data]                                                                                                  * TLSv1.3 (IN), TLS handshake, CERT verify (15):                                                                     { [264 bytes data]                                                                                                   * TLSv1.3 (IN), TLS handshake, Finished (20):                                                                        { [52 bytes data]                                                                                                    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):                                                          } [1 bytes data]                                                                                                     * TLSv1.3 (OUT), TLS handshake, Finished (20):                                                                       } [52 bytes data]                                                                                                    * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384                                                              * ALPN, server accepted to use http/1.1                                                                              * Server certificate:                                                                                                *  subject:                                                                                         *  start date: May 25 15:28:22 2021 GMT                                                                              *  expire date: Aug 23 15:28:22 2021 GMT                                                                             *  subjectAltName: host "" matched cert's ""                                               *  issuer: C=US; O=Let's Encrypt; CN=R3                                                                              *  SSL certificate verify ok.                     

This basic command is giving you a lot of valuable information. It’s identifying the server, and it’s showing you the certs common name as well.