WhoDNS
All articles

Does the Certificate Match the Key? Verifying Cert, Key and CSR Pairs

Every webmaster eventually meets this failure: you replace a certificate, reload nginx, and the reload dies with SSL_CTX_use_PrivateKey_file: key values mismatch. The files both look fine, both decode, both have the right domain. They simply do not belong together — and the server refuses to start because presenting a certificate you cannot prove ownership of is worse than serving none.

How match checking works

A certificate does not contain its private key; it contains the corresponding public key. Two files match when the public key in the certificate is the pair of the public key derived from the private key. The same logic links a CSR to a key: the CSR embeds a public key that must equal the certificate’s. Comparing public keys is the reliable method and works for both RSA and ECDSA:

openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa  -noout -modulus -in key.pem  | openssl md5
openssl req  -noout -modulus -in csr.pem   | openssl md5

If all three hashes are equal, the trio matches. For EC keys, use openssl pkey -pubout on each file and compare the printed public keys instead, since ECDSA has no modulus in the RSA sense.

Why mismatches happen

  • Reissued certificate, old key: the CSR was regenerated (common with ACME automation) but the server config still points at the previous key file.
  • Multiple keys on disk: example.com.key, example.com.key.bak, example.com.key.new — and the config references the wrong one.
  • Concatenated files: someone pasted a chain into the key file or vice versa during a rushed renewal.
  • Certificate replaced but the LB/CDN still terminates TLS: the origin and edge now hold different pairs, which looks like an outage but is really an inventory problem.

Recovering from a broken reload

  1. Do not restart the service while the mismatch persists — a reload usually keeps the old process alive, but a restart will fail and take TLS down completely.
  2. Identify the matching key with the modulus comparison above, testing every key file in the directory.
  3. Point the config at the correct key (or regenerate a CSR from the existing key and reissue, so the pair is guaranteed), then reload.
  4. Verify from outside before declaring victory: a scan of the live endpoint confirms the served chain is the new certificate, not a stale one.
  5. Update every copy of the pair — the CDN, the load balancer and any secondary origin server often hold their own versions of the old files.

Prevention is one habit: whenever you touch cert files, run the three-command comparison before the reload, not after the pager goes off. The cert/key match checker on WhoDNS does the public-key comparison for you — paste or upload the certificate, key and optionally the CSR, and it reports which of the three pairings match, catching the mismatch before nginx does.

certificate key matchmodulus comparisonnginx ssl errorkey mismatchCSR pairpemrecovery