bg-tutorials

How to Fix the Modulus Mismatch Error

A modulus mismatch means your SSL certificate and your private key are not a matching pair. The certificate was issued for one key, and the file your server is loading is a different key. Because a TLS server has to prove it holds the private key belonging to the certificate it presents, there is nothing to negotiate when the two do not correspond, so the server refuses to start rather than serve a connection it cannot complete.

This guide shows you how to confirm the mismatch with a single pair of commands, how to find the key that does match, what causes the mismatch in the first place, and what to do when the original key is genuinely gone.

Quick answer:

Compare the certificate and the key. For an RSA certificate, run openssl x509 -noout -modulus -in cert.crt | openssl md5 and openssl rsa -noout -modulus -in cert.key | openssl md5. Identical hashes mean the files are a pair, and different hashes confirm the mismatch.

For an ECDSA certificate the modulus check does not work, so compare public keys instead with openssl x509 -noout -pubkey and openssl pkey -pubout.

If no key on the server matches, the key is lost and cannot be recovered from the certificate: generate a new CSR and key pair, then reissue the certificate. Never paste a private key into an online matcher.

What a Modulus Mismatch Actually Means

An SSL certificate and a private key are two halves of one key pair. The certificate is a public document: it contains your domain name, the issuing CA, the validity dates, and the public half of the key. The private key file never leaves your server and holds the secret half. During every HTTPS connection the server uses the private key to prove it is the legitimate holder of the certificate it just presented.

For RSA keys, both halves share the same number, called the modulus. The modulus is the large integer that all RSA operations are performed against, and it appears in the public key and in the private key alike. That is what makes it a convenient fingerprint: if the modulus stored in the certificate is the same as the modulus stored in the key file, the two files belong together. If it differs, they do not, and the server has no way to complete a handshake.

Two consequences follow from this, and both matter when you are troubleshooting.

  • It is a startup error, not a browser error. The web server detects the problem when it reads its configuration, before it ever accepts a connection. Visitors do not see a certificate warning they can click through. They see a site that is simply down, because the server never came up.
  • The private key cannot be derived from the certificate. Recovering the key from the public certificate is the problem RSA is built to make infeasible. If the matching key is not somewhere on your infrastructure or in a backup, no tool and no support desk can reconstruct it, and reissuing is the only path forward.

What the Error Looks Like on Your Server

“Modulus mismatch” is the phrase Certificate Authorities and support desks use. It is worth knowing that no mainstream web server prints those two words. If you searched for this term after reading it in a support ticket, here is what your server actually logged.

Nginx

Nginx refuses to start and writes the underlying OpenSSL error to the log:

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

Older systems print a slightly different line. Nginx releases before 1.15.9 named the function SSL_CTX_use_PrivateKey_file, and OpenSSL 1.1.1 numbered the error differently while filling in the function that raised it:

nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/nginx/ssl/example.com.key") failed
(SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)

The empty pair of colons in the first example is not a typo. OpenSSL 3.x dropped the function codes that earlier versions recorded, and the server prints whatever remains, so the field between “routines” and the message is simply blank. Since both the number and the function name move around between versions, search your logs for the phrase key values mismatch, which is the one part that stays the same.

Nginx normally catches this while merging its configuration, so nginx -t fails and the service refuses to start. There is one exception: if ssl_certificate contains a variable, nginx loads certificates per connection instead, the configuration test passes, and the mismatch appears in the error log when a request arrives.

Apache

Current Apache 2.4 releases name both files in the error, which makes this the most useful message of the group:

[ssl:emerg] AH02565: Certificate and private key example.com:443:0 from
/etc/ssl/certs/example.com.crt and /etc/ssl/private/example.com.key do not match
AH00016: Configuration Failed

There is a trap here worth knowing about. Apache’s syntax check does not load the certificate and key, so apachectl configtest reports “Syntax OK” on a configuration that will fail the moment you actually restart the service. Always watch the error log after a restart, not just the output of the config test.

Apache 2.2, whose final release was 2.2.34 in July 2017 and which still turns up inside appliances and vendor images, reported the same condition in different words. It named the key type rather than the files, which is why it was much harder to act on:

Unable to configure RSA server private key

That wording does not exist in Apache 2.4. If your log shows it, you are running httpd 2.2, and the upgrade is worth scheduling for reasons well beyond this error.

Control panels and other stacks

cPanel, WHM, Plesk, and most hosting dashboards check the pair before they save it and reject the installation with a plain-language message such as “the certificate does not match the private key.” Windows and IIS express the same problem differently: the certificate appears in the store without the small key icon, and IIS reports that no private key is associated with it. Tomcat, load balancers, and mail servers all reduce to the same underlying OpenSSL check.

Save 10% on SSL Certificates when ordering from SSL Dragon today!

Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

A detailed image of a dragon in flight

How to Check Whether the Certificate and Key Match

Run these commands on the server that holds the files. They read the files and print a hash, they change nothing, and the private key never leaves the machine.

The modulus check for RSA certificates

This is the classic test and it still works. Print the modulus of the certificate and the modulus of the key, and hash each one so you are comparing two short strings instead of two long blocks of hex:

openssl x509 -noout -modulus -in example.com.crt | openssl md5
openssl rsa -noout -modulus -in example.com.key | openssl md5

When the files are a pair, the two hashes are identical:

MD5(stdin)= 7c2d6ebbfc33eed0a808de4deb71ca53
MD5(stdin)= 7c2d6ebbfc33eed0a808de4deb71ca53

When they are not, the hashes differ, and you have confirmed the mismatch:

MD5(stdin)= 7c2d6ebbfc33eed0a808de4deb71ca53
MD5(stdin)= f6a8a0d5b7eb02ea182edbe300358ed7

MD5 is used here only to shorten two values for eyeball comparison, not to protect anything, so its weakness as a security hash is irrelevant in this context. If you prefer, substitute openssl sha256 in both commands. What matters is that you use the same hash on both sides.

The check that works for every key type

Modulus is an RSA concept. ECDSA keys, which modern ACME clients now generate by default (Certbot has defaulted to ECDSA since version 2.0), have no modulus at all, and neither do Ed25519 keys. Instead of asking for the modulus, ask each file for the public key it carries and compare those:

openssl x509 -noout -pubkey -in example.com.crt | openssl sha256
openssl pkey -pubout -in example.com.key | openssl sha256

Identical hashes mean the files are a pair. This form is worth making your default, because openssl pkey reads RSA, ECDSA, and Ed25519 keys alike, so one pair of commands covers every certificate you are likely to install. If your OpenSSL is old enough that pkey is unavailable, the equivalent for an EC key is openssl ec -pubout -in example.com.key.

Why the modulus check cannot be trusted on ECDSA certificates

This deserves its own warning, because it fails in the most misleading way possible. Asking an ECDSA certificate for its modulus does not return an error. It prints a sentence:

Modulus=No modulus for this public key type

That sentence is then hashed like any other text, and every certificate whose key genuinely has no modulus produces exactly the same sentence, which covers ECDSA and Ed25519 alike, so the hash is a constant. Any comparison where both sides are certificates therefore returns a perfect but meaningless match: two completely unrelated ECDSA certificates hash identically. The wording depends on which build you have. OpenSSL 3.x prints the line above, while the LibreSSL that macOS ships as its own openssl prints “Modulus=Wrong Algorithm type” and omits the “MD5(stdin)= ” prefix from the hash. Both strings are constants, so both behave the same way.

The key side of the comparison fails differently, and just as quietly. Run openssl rsa -noout -modulus against an EC key and it stops with “Not an RSA key” (LibreSSL prints a longer “expecting an rsa key” error instead), sending that message to standard error and printing nothing to standard output. Piping nothing into a hash still produces a hash, so watch for this value:

MD5(stdin)= d41d8cd98f00b204e9800998ecf8427e

That is the MD5 of an empty input. It means your command produced no output at all, so it is a sign the command failed, not evidence that the files disagree. Put the two halves together and the result is worse than an error message. Run the RSA recipe against an ECDSA certificate and the very key it was issued for, and the two hashes differ, so a pair that is completely correct looks broken:

MD5(stdin)= baf59ff7f5b05fde6799439b6f31a290
MD5(stdin)= d41d8cd98f00b204e9800998ecf8427e

The first value is not a fingerprint of your certificate. It is the hash of that fixed sentence, so every ECDSA certificate prints it. The certificate side reports a false match against any other ECDSA certificate, and the key side reports a false mismatch against its own certificate, which is why the modulus recipe should never be used on anything but RSA. Confirm which algorithm you are dealing with before trusting any modulus output:

openssl x509 -noout -text -in example.com.crt | grep "Public Key Algorithm"

Checking the CSR as well

If you still have the CSR you submitted, it carries the same public key and can be compared the same way. This tells you whether the certificate was issued against the CSR you think it was:

openssl req -noout -modulus -in example.com.csr | openssl md5

That form is RSA-only for the same reason as above, and on an ECDSA request it is actively misleading: the request prints a fixed sentence rather than a modulus, which on macOS happens to be the identical sentence an ECDSA certificate prints, so the two appear to match no matter which files you compare. Use the public key instead, which works for every algorithm:

openssl req -noout -pubkey -in example.com.csr | openssl sha256

A CSR whose public key matches the key but not the certificate means the CA issued your certificate against a different request, which usually means a second CSR was generated somewhere along the way. You can also inspect a request with our CSR decoder, since a CSR contains no secret material and is safe to paste.

Do not paste your private key into an online matcher

Several sites offer to check a certificate and key for you if you paste both into a form. Avoid them, and treat this as the one hard rule of this guide. The moment your private key is transmitted to a third party, you no longer control who holds it, and the correct response is to treat the key as compromised: request revocation, generate a new key, and reissue. That is a far worse afternoon than the mismatch you were trying to diagnose.

It is also not something you can quietly postpone. The CA/Browser Forum Baseline Requirements oblige a Certificate Authority to revoke a certificate within 24 hours once it has evidence that the subscriber’s private key was compromised, and they oblige you, as the subscriber, to request revocation promptly and stop using the key as soon as you suspect misuse or compromise. If a key has already been pasted somewhere it should not have been, start that process rather than waiting to see whether anything happens.

The commands above do the identical comparison locally in about two seconds and give you the same answer, so there is nothing to gain from the exchange. Certificates, CSRs, and public keys are public by design and carry no such risk. Private keys are the one thing that must never leave the server, including in a support ticket, a chat message, or a screenshot.

What Causes a Modulus Mismatch

In practice the error comes from a small number of situations, and identifying which one you are in tells you whether the fix takes two minutes or requires a reissue.

  • The certificate was reissued against a new CSR. Generating a fresh CSR creates a fresh private key with it. If you reissue or renew using that new CSR but the server still points at the key from the original request, every file looks current and nothing matches. This is the single most common cause.
  • The key was overwritten during a renewal. A renewal script, a control panel, or a second administrator writes a new key to the same path the old one occupied. The certificate is untouched and still valid, but the key beneath it is no longer the one it was issued for.
  • The wrong file was picked from a directory of similar names. Directories accumulate names like server.key, server-old.key, example.com.key, and example.com.key.bak. Pointing the configuration one line off is easy and produces exactly this error.
  • A chain file was placed in the certificate field. This one is worth reading twice, because the certificate and key can be a genuine pair and the error still appears. Details below.
  • An ACME client is writing somewhere the server does not read. Certbot and similar clients renew into their own directory, commonly under /etc/letsencrypt/live/, and Certbot generates a brand new private key at every renewal unless you tell it otherwise. So if someone once copied the files into the web server’s own directory and the configuration still points at the copies, the copied key stops matching the moment the first renewal runs. Certbot’s documentation asks you to point your server configuration at its files directly, or to use symlinks, rather than copying them. The failure often surfaces weeks later, at the next restart, long after the renewal that caused it.
  • A control panel supplied its own key. cPanel, WHM, and Plesk keep their own key store and can attach a key they generated rather than the one that belongs to your certificate, particularly when the CSR was created outside the panel. Uploading the certificate and its key together, explicitly, avoids the guesswork.
  • Files were restored or copied without their partner. Restoring a certificate from a backup that did not include the key directory, or copying a certificate to a second server without moving its key, leaves the two halves in different places.

The chain file case, where the key is actually correct

When a certificate file holds more than one certificate, the server uses the first one in the file as its own and treats the rest as the chain. If the bundle was assembled with the intermediate or root first, the server compares your private key against the CA’s certificate rather than yours. They obviously do not match, and you get the same “key values mismatch” error even though your certificate and key are a perfect pair.

Nginx documents this behaviour directly, noting that the server certificate must appear before the chained certificates in a combined file. The correct order is your certificate first, then the intermediate, then any further CA certificates:

-----BEGIN CERTIFICATE-----
(your server certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(intermediate CA certificate)
-----END CERTIFICATE-----

Check which certificate your server is really reading by asking for the subject of the first one in the file. If it names a Certificate Authority instead of your domain, the order is wrong:

openssl x509 -noout -subject -in example.com-bundle.crt

Rebuild the file with your certificate on top and the error goes away without touching the key at all:

cat example.com.crt intermediate.crt > example.com-bundle.crt

How to Fix the Modulus Mismatch Error

Work through these steps in order. The first three resolve most cases without involving your CA.

1. Confirm which files the server is loading

Before comparing anything, find out which paths are actually configured. A surprising share of mismatches are really a configuration pointing at a file nobody expected. On nginx:

grep -R -i "ssl_certificate" /etc/nginx/

On Apache:

grep -R -i "SSLCertificate" /etc/apache2/ /etc/httpd/

Note every path returned, including ones in files you thought were disabled. Then identify what each certificate actually is, so you are not guessing from file names:

openssl x509 -noout -subject -issuer -dates -in example.com.crt

2. Find the private key that does match

If the server holds several keys, test them all at once instead of one by one. This loop compares every key in a directory against the certificate and prints the one that fits:

for k in /etc/ssl/private/*.key; do
  if [ "$(openssl pkey -pubout -in "$k" 2>/dev/null)" = \
       "$(openssl x509 -pubkey -noout -in /etc/ssl/certs/example.com.crt)" ]; then
    echo "MATCH: $k"
  fi
done

Widen the search if nothing turns up. Keys are often left in a home directory where a CSR was generated, in an ACME client’s directory, in a control panel’s key store, or in the backup taken before the last migration.

3. Repoint the configuration and reload

When the loop finds a match, update the configuration to reference that file, then test the configuration before restarting. On nginx:

sudo nginx -t && sudo systemctl reload nginx

On Apache, remember that the syntax check will not catch a mismatch, so check the error log after the reload rather than trusting the test alone:

sudo apachectl configtest && sudo systemctl reload apache2

Once the service is up, confirm what the site is serving from the outside with our SSL Checker, which reports the certificate in use, its expiry, and whether the chain is complete.

4. If the key is genuinely gone, reissue the certificate

When no key on the server matches, the original key is lost, and no support desk can recover it. Reissuing is the only remedy, and most CAs allow it free of charge for the remainder of the certificate’s term.

  1. Generate a new CSR on the server that will host the certificate, which creates a new private key alongside it. Our CSR generator is an alternative when your platform gives you no way to create one, but a CSR made off-server means you must transfer and install the key it produces, so prefer generating on the server itself when you can.
  2. Submit the new CSR to your CA through its reissue option, not as a new order.
  3. Complete validation again if the CA asks for it.
  4. Install the reissued certificate together with the new key, and confirm the pair with the commands above before reloading.

Keep the new key exactly where the CSR created it, and check its permissions before you move on. OpenSSL writes a new key readable only by the user that created it, and it should stay that way: on a Linux server, owned by root with mode 600, inside a directory that is not world-readable. Back it up somewhere with the same protection, not into a shared drive or a ticket attachment. Reissuing replaces the certificate, so any copy of the old certificate still deployed elsewhere continues to work until it expires, which is worth checking on load balancers and CDN nodes.

On Windows and IIS: repair the key association

Windows stores certificates and keys separately and links them by reference. If a certificate was imported without its key, or the link broke, the certificate shows in the store with no private key attached. When the key is still present on the machine, the link can be rebuilt. From a command prompt running under an account with administrative permissions, list the store and note the certificate’s serial number:

certutil -store my

Then repair the association, where my is the personal certificate store:

certutil -repairstore my "SerialNumber"

If you copied the serial out of the certificate details pane in the Microsoft Management Console, retype it or strip the spaces and any hidden formatting characters that the pane inserts, because they are copied along with the digits and cause the command to fail.

Microsoft documents -repairstore as repairing a key association, so it reconnects a certificate to a key Windows already holds. It cannot invent a key that was never imported. If the repair fails, import the original PFX file again, or reissue.

What Does Not Fix a Modulus Mismatch

General SSL troubleshooting advice circulates widely and most of it cannot affect this error, because the failure happens inside your server before any client is involved. The following steps waste time here.

  • Anything done in a browser. Clearing the cache, opening a private window, trying another browser or another device, or flushing the operating system’s SSL state. No visitor ever reached the point where their browser mattered.
  • Correcting the clock. A wrong system date causes expiry and validity warnings, which are a different problem entirely. The modulus comparison does not involve dates.
  • Restarting the server without changing the configuration. The check runs on every start and will fail identically every time.
  • Changing TLS versions or cipher suites. Protocol and cipher settings govern how a handshake is negotiated. This failure occurs before any handshake is attempted.
  • Reinstalling the same two files. Uploading the identical certificate and key through a control panel changes nothing about whether they are a pair.
  • Renewing with the original CSR when the key is lost. This is the subtle one. A renewal issued against the old CSR produces a certificate for the old key, which is precisely the key you no longer have. Generate a new CSR, and therefore a new key, instead.
  • Editing the PEM files by hand. Adjusting line breaks or trimming characters cannot make two unrelated keys correspond, and it usually corrupts a file that was fine. The exception is reordering whole certificates in a bundle, which is a different fix and is covered above.

How to Avoid It Next Time

A few habits remove most of the ways this error appears.

  • Name files so the pair is obvious. Use the domain and the issue date in both file names, and delete superseded keys once the new certificate is confirmed working rather than leaving them to be selected by mistake later.
  • Generate the CSR where the certificate will live. This keeps the key on the server from the start and removes the transfer step where keys get lost or swapped.
  • Verify the pair before reloading, not after. One comparison takes seconds and turns an outage into a non-event.
  • Point the configuration at the renewal directory. Reference the path your ACME client writes to instead of copying files elsewhere, so renewals land where the server reads.
  • Automate renewals. Certificate lifetimes are shortening on a fixed schedule agreed by the CA/Browser Forum. Public certificates issued on or after March 15, 2026 are capped at 200 days, dropping to 100 days in March 2027 and 47 days in March 2029. Every one of those renewals is an opportunity for a key to be regenerated by hand and land in the wrong place. Tools built on ACME automation request, install, and renew certificates together with their matching keys, which removes the step where the two drift apart.

Frequently Asked Questions

Can I recover my private key from the certificate?

No. Deriving the private key from the public certificate is the exact problem that RSA and ECDSA are designed to make computationally infeasible, which is also why the whole system is trustworthy. No tool, CA, or hosting provider can do it. If the key is not on your servers or in a backup, reissue the certificate against a new CSR.

Do visitors see a “modulus mismatch” error?

No. The server detects the problem while reading its configuration and refuses to start, so there is nothing listening on port 443. Visitors get a connection error or a timeout, not a certificate warning. If your visitors are seeing a certificate warning in the browser, you are looking at a different problem, such as an untrusted issuer or an expired certificate.

My certificate and key do match, but the server still reports a mismatch. Why?

Two explanations cover nearly all of these. Either the certificate file is a bundle with the CA certificate first, so the server is comparing your key against the CA’s certificate rather than yours, or the configuration points at a different file from the one you tested. Print the subject of the first certificate in the file, and confirm the configured paths with a grep of the server configuration.

Why does the modulus check give the wrong answer on my ECDSA certificate?

Because the check is RSA-only, and neither half of it fails loudly. Asking an ECDSA certificate for a modulus returns a fixed sentence rather than an error, and because every ECDSA certificate returns the same sentence, two unrelated certificates hash identically and appear to match. Asking an EC key for a modulus prints nothing at all, which hashes to d41d8cd98f00b204e9800998ecf8427e, the hash of an empty input. So the certificate and the key it was issued for still produce two different hashes, and a correct pair looks broken. Compare public keys instead, using openssl x509 -noout -pubkey against openssl pkey -pubout.

Is it safe to use an online tool to check whether my certificate and key match?

Not if it asks for the private key. Sending a private key to any third party means you can no longer say who holds it, and the correct response afterwards is to request revocation promptly and reissue with a new key. Run the comparison locally instead. Tools that only take a certificate, a CSR, or a public key are perfectly safe, because none of those contain secret material.

Does a mismatch mean my certificate is invalid?

No. The certificate is still valid and still issued to your domain. The problem is only that the server is pairing it with the wrong key. Once you supply the key it was issued for, the same certificate works for the rest of its term with no reissue needed.

Why did Apache’s configuration test pass but the restart fail?

Apache’s syntax check validates the configuration file but does not load the certificate and key, so a mismatched pair passes it and reports “Syntax OK”. The check only happens when the service actually initializes TLS, which is when it logs AH02565 and stops. Always confirm a restart succeeded by reading the error log, rather than relying on the config test.

For more SSL error troubleshooting, check our detailed tutorials about fixing different SSL errors.

Save 10% on SSL Certificates when ordering from SSL Dragon today!

Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

A detailed image of a dragon in flight
Written by

I've been writing for SSL Dragon for over 10 years, focusing entirely on SSL certificates and digital security. My job is to take complex cybersecurity topics and strip away the jargon, making sure you get the clear, practical information you need to keep your website safe.