ERR_BAD_SSL_CLIENT_AUTH_CERT is one of the few Chrome errors that is about your certificate, not the website’s. Most SSL warnings appear because something is wrong with the certificate a server presents to you. This one appears because the server asked your browser to prove who it is, and the certificate your browser offered was missing, expired, or unusable.
That distinction changes the whole troubleshooting path. In this guide we explain what the error really means, what causes it, and how to fix it both as a visitor trying to reach a site and as the administrator running one.
Quick answer:
ERR_BAD_SSL_CLIENT_AUTH_CERT (Chromium error -117) means the site uses mutual TLS and rejected the client certificate your browser sent, or your browser sent none at all.
Fix it on the client side: install the client certificate the site issued you into the right store (Windows Personal store, macOS login keychain, Chrome’s own NSS database on Linux), confirm it has not expired and still has its private key, insert your smart card and enter the PIN if one is used, then fully quit and reopen Chrome so it forgets the certificate choice it cached for that site. Renewing the website’s own SSL certificate does not fix this error.
Table of Contents
- What Is the ERR_BAD_SSL_CLIENT_AUTH_CERT Error?
- What Causes the ERR_BAD_SSL_CLIENT_AUTH_CERT Error?
- How to Fix the ERR_BAD_SSL_CLIENT_AUTH_CERT Error as a Website Visitor
- How to Fix the ERR_BAD_SSL_CLIENT_AUTH_CERT Error as a Website Owner
- Frequently Asked Questions
What Is the ERR_BAD_SSL_CLIENT_AUTH_CERT Error?
ERR_BAD_SSL_CLIENT_AUTH_CERT is Chromium network error -117. The Chromium source defines it in one line: the SSL handshake failed because of a bad or missing client certificate. Chrome, Edge, Brave, Opera, and every other Chromium-based browser share that definition, which is why the error text is identical across them.
In an ordinary HTTPS connection, only the server proves its identity. Your browser checks the server’s certificate, confirms a certificate authority (CA) it trusts issued it, and the SSL handshake completes. You are never asked to identify yourself at the TLS layer.
Some sites run mutual TLS, also called mTLS, two-way TLS, or client certificate authentication. There, the server sends a certificate request during the handshake, and the browser has to answer with a certificate of its own plus a signature proving it holds the matching private key. If the browser has nothing to send, sends something the server will not accept, or cannot produce that signature, the handshake stops and Chrome shows ERR_BAD_SSL_CLIENT_AUTH_CERT.
You will normally meet mutual TLS in places where a password alone is not considered enough:
- Corporate intranets, admin consoles, and VPN portals.
- Government and tax filing portals that issue citizens a personal certificate or a smart card.
- Banking, brokerage, and payment back offices.
- Healthcare systems and other regulated environments.
- API gateways and machine-to-machine endpoints.
Make sure you are looking at the right error
This is worth checking before you change anything, because a lot of advice about this error describes a different problem. If the site never asked you for a certificate, and you have never been issued one for it, then a client certificate is almost certainly not what is failing. Chromium reports problems with the server’s certificate under separate codes:
- NET::ERR_CERT_DATE_INVALID (-201): the server’s certificate has expired or is not yet valid, or your clock is wrong.
- NET::ERR_CERT_AUTHORITY_INVALID (-202): the server’s certificate is signed by an authority your browser does not trust, which usually means a missing intermediate certificate or a self-signed certificate.
- NET::ERR_CERT_REVOKED (-206): the server’s certificate was revoked by its CA.
Those are the errors that installing, renewing, or re-chaining a website’s SSL certificate resolves. ERR_BAD_SSL_CLIENT_AUTH_CERT is not one of them.
Related client authentication error codes
Chromium has a whole family of client authentication errors, and the one you get narrows the cause considerably. If Chrome’s error page or chrome://net-export shows one of these instead, read it as a more specific version of the same failure:
- ERR_SSL_CLIENT_AUTH_CERT_NEEDED (-110): the server requested a client certificate.
- ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED (-134): permission to use the certificate’s private key was denied, typically a keychain or smart card prompt that was cancelled.
- ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY (-135): the certificate is installed but its private key is not.
- ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED (-141): the key exists but could not sign, often a removed smart card or a stale key handle.
- ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT (-164): the browser could not import the certificate out of the platform store.
- ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS (-177): your key and the server share no signature algorithm.
Where client certificates live on each platform
Chrome does not keep its own list of client certificates on most systems. It reads whatever the operating system holds, so the error can differ between two machines belonging to the same person:
- Windows: the current user’s Personal store. Chrome and Edge both read it, so a certificate that works in one normally works in the other.
- macOS: the login keychain in Keychain Access, under My Certificates.
- Linux: Chrome’s own NSS database, not the system trust store. Importing a certificate system-wide does not make it available to the browser.
- Android: the user credentials store, populated under Settings and Encryption & credentials by installing a VPN & app user certificate. Our guide on installing a certificate on Android walks through it.
- iOS: a configuration profile, under Settings and General, then VPN & Device Management.
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
What Causes the ERR_BAD_SSL_CLIENT_AUTH_CERT Error?
Every cause below breaks the same step: the browser cannot hand the server an acceptable certificate and prove it owns the matching key. They are ordered roughly by how often they turn up.
No client certificate installed, or the prompt was dismissed
When a server requests client authentication, Chrome opens a certificate picker listing the certificates that match the request. If nothing on your machine matches, the list is empty. If you close the dialog or click Cancel, the browser sends an empty certificate message instead.
TLS 1.3 leaves the next move to the server: it may continue without authenticating you, or it may abort the handshake with a certificate_required alert. Servers protecting private resources almost always abort, which is what surfaces as this error. So an empty picker and a cancelled picker produce the same page, and neither is a browser bug.
The client certificate expired or was revoked
This is the most common cause on corporate, government, and banking portals, because these certificates are usually issued for a fixed term and quietly lapse. Once past its notAfter date, the certificate is still sitting in your store and still appears in the picker, so nothing looks wrong locally. The server does the date check and refuses it.
Revocation produces the same result and is more abrupt. If the issuing CA published your certificate on a Certificate Revocation List, or marks it revoked over OCSP, a server that checks revocation rejects it even though the dates are still valid. Certificates get revoked when a laptop is lost, when a private key is exposed, or when someone leaves an organization.
The certificate was issued by a CA the server does not trust
The server does not accept just any certificate. It advertises which issuers it will accept, and it validates what you send against its own client CA bundle, which is usually a private internal CA rather than a public one. A certificate from a different department’s CA, from a replaced CA, or from a public CA will be refused even though it is perfectly valid in every other respect.
A missing intermediate has the same effect. If your certificate chains through an intermediate the server does not hold and your browser does not send, the server cannot build a path to a root it trusts and the handshake fails.
The private key is missing or inaccessible
A certificate on its own is not enough. It is public information, so the server also asks for a signature that only the private key holder can produce. Anything that separates the two breaks authentication:
- The certificate was imported from a .cer or .crt file, which carries no key, instead of from a .p12 or .pfx bundle that carries both.
- A smart card, PIV card, or hardware token was removed, or its middleware is not running.
- The macOS keychain holding the key is locked, or a permission prompt was declined.
- The key was marked non-exportable on the machine it was created on and never made it onto the new one.
- A Windows user profile was rebuilt, leaving the certificate in place but the key gone.
No signature algorithm in common
The client and server also have to agree on how the authentication signature is produced. TLS 1.3 dropped RSASSA-PKCS1-v1_5 for handshake signatures, keeping it only for signatures inside certificates. Hardware that can only perform PKCS#1 v1.5 signing, which describes plenty of older smart cards and hardware security modules, therefore has nothing to offer a TLS 1.3 server. Chromium reports the clean version of this as ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS, but a partial mismatch can surface as ERR_BAD_SSL_CLIENT_AUTH_CERT instead. Certificates still using SHA-1 run into the same wall on modern servers.
A TLS-inspecting proxy or antivirus is in the way
Antivirus HTTPS scanning, corporate web filters, and enterprise proxies work by terminating your TLS connection and opening a second one to the real server. Mutual TLS cannot survive that, because the proxy does not hold your private key and cannot produce the signature on your behalf. Most such products have an exclusion list for exactly this reason.
This is also the honest explanation behind the common advice to disable a VPN. A plain VPN only moves your traffic and does not touch the handshake. A VPN client that also filters or inspects HTTPS does, and that is the part that breaks client authentication.
Chrome cached the wrong certificate choice
Chrome remembers which certificate you picked for a given host and port so it does not prompt you on every request. That memory includes the decision to send nothing at all. Cancel the picker once, or pick the wrong certificate once, and the browser keeps reusing that choice for the same site.
The cache is held in memory only, so it survives page reloads but not a browser restart. That is why a site that failed all morning starts working after a genuine quit and relaunch, and why reloading with a hard refresh changes nothing.
The device clock is wrong
Certificate validity is judged against the clock on the machine doing the checking. If your device’s date is far enough off, your browser can decide your own client certificate is expired or not yet valid and leave it out of the picker, so you are back to sending nothing. A drifting server clock causes the mirror image of the same problem.
Client authentication is misconfigured on the server
The server side fails in its own ways: client authentication left as required on a site that was never meant to use it, a client CA bundle pointing at the wrong file or an old CA, a verification depth too shallow for the chain in use, or an expired CRL that makes the server reject every certificate at once. When several people lose access simultaneously, the server is almost always where the problem is.
How to Fix the ERR_BAD_SSL_CLIENT_AUTH_CERT Error as a Website Visitor
Work through these in order. Unlike most SSL errors, the visitor genuinely can fix this one, because the failing certificate is on your machine.
1. Restart the browser completely
Do this first because it costs nothing and clears the cached certificate choice described above. Closing the window is not enough on Windows if Chrome keeps running in the background, and on macOS you need Quit rather than the red close button. Reopen the browser, load the site, and let the certificate picker appear again.
When it does appear, read it before clicking. If the list is empty or none of the entries look like a certificate issued to you by this organization, continue to the next step rather than picking one at random.
2. Confirm the client certificate is installed, with its key
On Windows: press Windows + R, then run the Certificate Manager:
certmgr.msc
Open Personal, then Certificates. Your certificate should be listed with an expiry date in the future. Double-click it: the General tab must say you have a private key corresponding to the certificate. If it does not, the certificate was imported without its key and has to be reinstalled from the original .p12 or .pfx file. Check the Details tab too, where Enhanced Key Usage needs to include Client Authentication. Certificates issued for a machine rather than a person live in the local computer store, which opens with certlm.msc instead.
On macOS: open Keychain Access, select the login keychain, and click My Certificates. That category only lists certificates that have a usable private key, so an entry appearing under All Items but not under My Certificates is itself the diagnosis. Expand the certificate with the disclosure triangle to confirm the key sits beneath it, and check that the keychain is unlocked.
On Linux: Chrome reads its own NSS database instead of the system trust store. Install the NSS tools first:
sudo apt install libnss3-tools
List what Chrome can currently see:
certutil -d sql:$HOME/.local/share/pki/nssdb -L
If your certificate is not listed, import the bundle that contains both the certificate and its key:
pk12util -d sql:$HOME/.local/share/pki/nssdb -i client-cert.p12
Chromium moved this database in version 146. Releases from 146 onward use the path shown above, while older installations, and any machine that still has the previous database, use $HOME/.pki/nssdb. If the commands above report nothing on a system that used to work, retry them against the old path.
3. Check the certificate’s validity dates
An expired client certificate is the single most frequent cause of this error, and the expiry is easy to miss because the certificate stays in the store afterwards. If you still have the original file, read its dates with OpenSSL:
openssl x509 -in client-cert.pem -noout -subject -issuer -dates
For a PKCS#12 bundle, read the certificate out of it first:
openssl pkcs12 -in client-cert.p12 -clcerts -nokeys | openssl x509 -noout -subject -issuer -dates
Compare notAfter against today’s date. If it has passed, no local change will help: request a replacement from whoever issued it, which is your IT department, your bank, or the government agency running the portal. The same applies if the certificate was revoked.
4. Check your smart card, token, or PIN
If your certificate lives on a smart card, PIV card, or USB token, the certificate can be visible while the key is unreachable. Reseat the card, confirm the reader is recognized by the operating system, and make sure the vendor middleware is installed and running. Enter the PIN when prompted rather than dismissing the dialog, and remember that too many wrong attempts can lock the card and require an administrator to unlock it.
Removing the card mid-session leaves Chrome holding a key handle that no longer works, which typically shows up as ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED. Restarting the browser after reinserting the card clears it.
5. Correct your device’s date and time
A clock that is off by days or years makes your browser treat a valid certificate as expired. Synchronizing it with a time server is the reliable fix, rather than typing the time in by hand.
On Windows:
- Right-click the clock in the taskbar and choose Adjust date and time.
- Turn on Set time automatically and confirm the time zone is correct.
- Click Sync now to force an immediate synchronization.

On macOS:
- Open the Apple menu and choose System Settings.
- Click General in the sidebar, then Date & Time.
- Turn on Set time and date automatically and check that the Mac is online.
On macOS Monterey and earlier the same settings sit under System Preferences and Date & Time, where you unlock the pane with the padlock icon and your administrator password before anything can be changed, as shown below.

Restart the browser after correcting the clock.
6. Turn off HTTPS scanning in your security software
Look for a setting named HTTPS scanning, SSL scanning, encrypted connections scanning, or web shield in your antivirus, and switch it off temporarily. If the site then works, you have found the cause: add the site to the product’s exclusion list and turn the scanning back on rather than leaving it disabled.
Disable the whole antivirus only if it offers no separate HTTPS setting, and re-enable it as soon as the test is done. On a managed work device you may not be able to change this at all, in which case your IT team has to add the exclusion centrally. The same applies to a corporate VPN or web filter that inspects traffic.
7. Test in a different browser or profile
This tells you where the problem sits. On Windows, Chrome and Edge share the same certificate store, so a site that fails in both points at the certificate rather than at one browser’s state. Firefox keeps its own separate store, so a site that works only in Firefox usually means the certificate was imported there and nowhere else. An Incognito window is useful too: it starts with an empty certificate decision cache, so it forces the picker to appear without a full restart.
8. Contact whoever issued your certificate
If the certificate is expired, revoked, or was never issued to you, only the issuer can resolve it. When you get in touch, say which site fails, the exact error, and the subject and expiry date of the certificate you are trying to use. That is usually enough for them to tell you whether it lapsed, was revoked, or was issued by a CA the portal has since stopped accepting.
How to Fix the ERR_BAD_SSL_CLIENT_AUTH_CERT Error as a Website Owner
Before changing anything, be clear about which certificate is failing. Your server’s own certificate is not involved in this error. Reissuing it, re-chaining it, or renewing it early will not change the outcome. What matters is how your server requests and validates client certificates.
1. Check whether you meant to require client certificates
If nobody can reach the site and you never intended to use mutual TLS, client authentication was probably enabled by a template, a hardening guide, or a copied virtual host block. On Apache, look for:
SSLVerifyClient require
SSLVerifyDepth 3
SSLCACertificateFile /etc/ssl/certs/client-ca-bundle.crt
On nginx, the equivalent is:
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/client-ca-bundle.crt;
ssl_verify_depth 3;
Setting the directive to none on Apache or off on nginx disables client authentication entirely. If you want it on some paths only, scope the requirement to a location block rather than the whole server, so the public part of the site stays reachable.
2. Verify the client CA bundle
This is the most common server-side cause. The file named by SSLCACertificateFile or ssl_client_certificate is what your server validates client certificates against, and it must contain the issuing CA of every certificate you expect to accept, including intermediates. It has nothing to do with the CA bundle that serves your own certificate, and mixing the two is a frequent mistake.
Confirm the file actually holds what you think it does:
openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/client-ca-bundle.crt | openssl pkcs7 -print_certs -noout
On nginx there is a second consideration. ssl_client_certificate sends the list of acceptable CA names to the browser, which is what populates the certificate picker. ssl_trusted_certificate validates against the same file but sends nothing, so users see an empty picker and get this error even though their certificate would have been accepted. Use the first unless you have a reason not to.
Also check SSLVerifyDepth or ssl_verify_depth. Both default to 1, which is too shallow for a chain that passes through more than one intermediate, and the rejection looks identical to an untrusted CA.
3. Check revocation settings
If you validate client certificates against a CRL, an expired CRL file rejects every client at once. This is a classic cause of a site that worked yesterday and fails for everyone today. The relevant directives are SSLCARevocationFile on Apache and ssl_crl on nginx, and when intermediates are involved their CRLs belong in the same file. On Apache the file alone changes nothing, because SSLCARevocationCheck defaults to none; set it to chain for the CRL to be consulted at all. Confirm the CRL is current:
openssl crl -in /etc/ssl/certs/client-ca.crl -noout -lastupdate -nextupdate
If nextUpdate is in the past, refresh the file and reload the server. CRLs need a scheduled refresh, not a one-time copy.
4. Reproduce the handshake from the command line
OpenSSL shows you exactly what your server asks for. First connect without a client certificate:
openssl s_client -connect example.com:443 -servername example.com
Look for the Acceptable client certificate CA names block in the output. Those are the issuers your server is advertising, and a browser will only offer certificates that match them. If the block is missing or reads No client certificate CA names sent, your CA bundle is not being loaded, which is why users see an empty picker.
Then repeat the connection presenting a real client certificate:
openssl s_client -connect example.com:443 -servername example.com -cert client-cert.pem -key client-key.pem
Read that output carefully, because the Verify return code line does not answer this question. It reports how OpenSSL judged the server’s certificate, so it reads 0 (ok) whether the server accepted your client certificate or refused it. Under TLS 1.3 the server validates your certificate after the handshake has already completed on your side, so a rejection tends to arrive afterwards rather than as a failed connection.
Request a page instead, and let the response settle it:
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' | openssl s_client -connect example.com:443 -servername example.com -cert client-cert.pem -key client-key.pem -quiet
A normal application response means the server accepted the certificate and the problem is on the client. A 400 mentioning a required or invalid certificate, or a TLS alert, reproduces the user’s failure on your own machine, where you can read the server logs at the same moment.
5. Read the server logs
The server records why it refused, and this is far quicker than guessing. On nginx, log the verification result by adding these variables to your log format:
log_format mtls '$remote_addr $ssl_client_verify $ssl_client_s_dn $ssl_client_i_dn';
The $ssl_client_verify variable returns SUCCESS when validation passed, NONE when no certificate was presented, and FAILED with a reason string when one was rejected. That reason distinguishes an expired certificate from an unknown issuer immediately. On Apache, raise the log level for mod_ssl and read the error log while reproducing the failure.
6. Check your server software version
Client authentication under TLS 1.3 depends on the TLS library underneath your web server, and very old builds handle it poorly or not at all. Check the web server and the OpenSSL version that performs the actual verification:
apache2 -v
nginx -v
openssl version
Back up your configuration before updating, and run the syntax check before reloading:
sudo apachectl configtest
sudo nginx -t
7. Consider automatic certificate selection for managed devices
If your users are on managed machines and the picker itself is the friction, Chrome’s AutoSelectCertificateForUrls policy lets administrators pre-select which certificate goes to which site, filtered by issuer or subject. The policy narrows the choice but never overrides the server’s request, so only certificates the server would have accepted are eligible.
Frequently Asked Questions
It means the website asked your browser to identify itself with a certificate, and the certificate your browser offered was rejected, or none was offered. Chromium assigns it error code -117 and defines it as a handshake failure caused by a bad or missing client certificate. The word client is the important one: the problem is the certificate on your device, not the certificate on the website.
Because your website’s certificate was never the cause. This error is raised over the certificate the browser sends to the server, so replacing the one the server sends to the browser changes nothing. You can confirm the server side is healthy by scanning the site with our free SSL Checker. A clean report alongside a continuing error is the clearest sign that client authentication is what needs attention: check the client CA bundle, the verification depth, and the CRL.
Usually one of three reasons. No certificate on your device matches what the server asked for, so the list would be empty. Or the browser already remembers a choice for that site, including a previous decision to send nothing, and reuses it silently until you restart. Or the server is not advertising its acceptable CA names, in which case the browser has nothing to filter on and the site owner needs to fix the configuration.
Quit the browser completely and reopen it. Chrome keeps client certificate decisions in memory, keyed to each host and port, and that store is not written to disk, so a full restart clears it. Closing a tab or reloading the page does not. An Incognito window works as a quick alternative, since it begins with no cached decisions.
Yes, but on a schedule set by whoever issues them, which is normally an employer’s internal CA or a government identity provider rather than a public CA. One to three years is typical, and smart card credentials are often tied to a badge or contract renewal instead.
Publicly trusted certificates for websites follow a separate and much shorter timetable. 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. If you run the server, those renewals are worth handing to automated certificate management via ACME, which performs domain validation, issuance, installation, and renewal before the previous certificate lapses.
No. It generally means the opposite. The site is enforcing an additional layer of authentication that most websites do not use, and it refused a connection it could not verify. Unlike a warning about an expired certificate on the server, there is no option to proceed anyway, because the handshake itself never completed.
Only if it inspects HTTPS traffic. A VPN that simply tunnels your connection leaves the handshake untouched. A corporate proxy, web filter, or antivirus that terminates TLS to scan content does break it, because it cannot present your certificate or sign with your private key on your behalf. Adding the site to the product’s inspection exclusion list is the correct fix.
In normal HTTPS only the server presents a certificate, and the browser verifies it. The visitor stays anonymous at the TLS layer and proves who they are later, with a password or a one-time code. In mutual TLS both sides present certificates during the same handshake, so the connection is only established if the server can also verify the visitor. It is stronger, which is why it appears on internal and regulated systems, and more fragile, because every user needs a valid certificate and a working private key on the device they are using.
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

