key values mismatch

The error "key values mismatch" means the private key configured does not correspond to the certificate configured — they are from two different key pairs. Confirm it by comparing the public key each one carries — `openssl pkey -in private.key -pubout | openssl sha256` and `openssl x509 -in certificate.crt -noout -pubkey | openssl sha256`. Different hashes confirm the mismatch. There is no way to repair it: a certificate certifies one specific public key, so you must find the matching private key or generate a new key, submit a new CSR and have the certificate reissued.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

Confirm it #

Two hashes that should match and do not
openssl pkey -in private.key -pubout | openssl sha256
openssl x509 -in certificate.crt -noout -pubkey | openssl sha256
Expected output
SHA2-256(stdin)= 9d4c1f2e8a3b...
SHA2-256(stdin)= 5f2a8c1d4e7b...

Different output confirms the diagnosis. This test works for RSA and EC keys alike, unlike the -modulus comparison you will find in older answers — see why.

Find the right key #

Before reissuing, look for the key that does match. It is often still on the machine.

Test every candidate key against the certificate
target=$(openssl x509 -in certificate.crt -noout -pubkey | openssl sha256)
for k in /etc/ssl/private/*.key /etc/ssl/private/*.pem; do
[ -e "$k" ] || continue
if [ "$(openssl pkey -in "$k" -pubout 2>/dev/null | openssl sha256)" = "$target" ]; then
  echo "MATCH: $k"
fi
done

Places worth checking:

  • Other paths under /etc/ssl/private/ and /etc/pki/tls/private/
  • The machine the CSR was originally generated on, which is often not this one
  • A .pfx the certificate was delivered in — extract the key from it
  • Configuration backups, your secrets manager, or the previous host during a migration

Check you have the right certificate too #

Sometimes the key is fine and the wrong certificate got deployed — easy on a host serving several sites:

openssl x509 -in certificate.crt -noout -subject -ext subjectAltName

If that names a different site than the one you are configuring, you have found the problem.

When the key is genuinely gone #

There is no recovery. Generate a new key, submit a new CSR, and have the certificate reissued:

openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key -out example.com.csr \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com"

Most CAs reissue for the remaining term at no charge. With ACME, it is a single renewal command.

Avoiding it next time #

  • Generate the key and CSR on the machine that will serve the certificate, and keep them together.
  • Never regenerate the CSR after ordering — that creates a new key and orphans the certificate.
  • Verify the pair as a deploy step, before reloading the service:
[ "$(openssl pkey -in private.key -pubout | openssl sha256)" \
= "$(openssl x509 -in certificate.crt -noout -pubkey | openssl sha256)" ] \
|| { echo "key/cert mismatch — refusing to reload"; exit 1; }

Frequently asked questions

Can I fix a mismatch without reissuing?
Only by finding the correct private key. The certificate contains one specific public key, and only its counterpart can complete a TLS handshake. Nothing about the certificate can be edited — doing so would invalidate the CA's signature.
What usually causes this?
Regenerating the CSR (and therefore the key) after ordering the certificate, mixing up files during a multi-site deploy, or restoring a key from a backup that predates the last rotation.
The files look identical in size — does that mean anything?
No. Two RSA 2048 keys are the same size and completely unrelated. Only the public key comparison tells you anything.
nginx -t passes but the browser still errors — is this the same thing?
No. nginx -t would catch a key mismatch. A config that tests clean but fails in browsers is usually a missing intermediate — see that error.

References