Servers and proxies

Nginx "key values mismatch": certificate and key don't match

By · Last verified

Error messagenginx: [emerg] SSL_CTX_use_PrivateKey("/etc/nginx/ssl/example.com.key") failed (SSL: error:05800074:x509 certificate routines::key values mismatch)

key values mismatch means the private key Nginx loaded does not belong to the certificate it loaded. Nginx checks the key against the first certificate in the ssl_certificate file, so the cause is either the wrong key file or a chain file in the wrong order.

Quick fix

Different public key hashes mean the key and the certificate are not a pair.

Compare the public key inside the certificate with the public key derived from the private key:

openssl x509 -in /etc/nginx/ssl/example.com.crt -noout -pubkey | openssl sha256
openssl pkey -in /etc/nginx/ssl/example.com.key -pubout | openssl sha256
  • Hashes differ: find the key that belongs to this certificate (or get the certificate reissued with a new CSR).
  • Hashes match: the first certificate in the file is fine, so check the file you reference; run nginx -T | grep -E "ssl_certificate(_key)?" to see every path, including other server blocks and includes.

Then test and reload:

sudo nginx -t && sudo systemctl reload nginx

Causes

1. The key belongs to a different certificate or CSR

This happens when a CSR is generated twice and the certificate is issued for the second one, when files from different renewals are mixed, or when a key from another domain is copied.

  • Confirm: the hashes above differ. Check other candidate keys the same way; the CSR used for the order also contains the public key: openssl req -in example.com.csr -noout -pubkey | openssl sha256.
  • Fix: use the matching key. If none matches, create a new key and CSR with the CSR generator or OpenSSL and ask the CA to reissue.

2. The intermediate comes before the leaf in the chain file

Nginx uses the first certificate in ssl_certificate as the server certificate. If the CA bundle is concatenated first, Nginx compares your key with the intermediate's public key.

  • Confirm: openssl x509 -in fullchain.crt -noout -subject shows the CA's name instead of your domain.
  • Fix: rebuild the file with the leaf first:
cat example.com.crt ca-bundle.crt > fullchain.crt

The chain builder produces a correctly ordered file.

3. Paths swapped or pointing to stale copies

  • Confirm: nginx -T shows ssl_certificate_key pointing at an old copy, a backup directory, or the certificate file itself.
  • Fix: point both directives at the current pair; for Let's Encrypt use the live/ symlinks, which always point at a matching pair.

4. Hidden characters or merged files

Copy-pasting through Windows editors or web panels can merge two PEM blocks or drop a line.

  • Confirm: openssl x509 -in file -noout or openssl pkey -in file -noout fails to parse.
  • Fix: re-download the files from the CA or panel and convert line endings with dos2unix if needed.

Fixes by environment

Whatever produced the files, the fix is the same: pair the key with the certificate issued for its CSR and put the leaf first. Apache reports the same problem as AH02572.

Let's Encrypt (Certbot):

ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

acme.sh: do not point Nginx at ~/.acme.sh/; run acme.sh --install-cert -d example.com --key-file ... --fullchain-file ... --reloadcmd "systemctl reload nginx" so both files are copied together on every renewal.

Commercial certificates: the CA sends the leaf and a CA bundle separately; concatenate leaf first. The key is the one generated with your CSR, usually on your server or in the panel where you created the CSR.

ECDSA and RSA dual certificates: when you configure two ssl_certificate / ssl_certificate_key pairs, each key must follow its own certificate in the same order.

Docker / Kubernetes: a TLS Secret's tls.crt and tls.key must also match; check them with the same commands after kubectl get secret ... -o jsonpath.

Don't do this

  • Generate a "new key for the existing certificate". It cannot match; you will only overwrite the correct key if it still exists somewhere.
  • Restart Nginx without nginx -t. A failed start takes every site on the server offline, not only this one.
  • Email or chat the private key to whoever is debugging. Share the public key hash instead; if the key was exposed, reissue the certificate with a new key.

FAQ

Can I regenerate the key to match the certificate?

No. The certificate contains one specific public key, and only the private key generated with it will match. If the key is lost, generate a new key and CSR and have the certificate reissued; most CAs reissue for free during the validity period.

Is it safe to paste my private key into an online matcher?

Avoid it. Compare the public key hashes locally with openssl; the key matcher also works because it runs in your browser and uploads nothing, but a private key is safest when it never leaves the server.

Why did it break right after a renewal?

Most often the new certificate was installed but the old key kept, or vice versa. ACME clients that rotate keys write both files at once; copy both, or point Nginx at the client's live paths (/etc/letsencrypt/live/<name>/fullchain.pem and privkey.pem).

Does the error stop the whole Nginx server?

Yes. nginx -t fails and a reload is refused, so the old configuration keeps running if Nginx was already up. A full restart with the broken files would leave Nginx stopped, so always run nginx -t first.

Sources

  1. nginx ngx_http_ssl_module
  2. nginx: Configuring HTTPS servers
  3. OpenSSL openssl-x509
  4. OpenSSL openssl-pkey