# SSL_ERROR_HANDSHAKE_FAILURE_ALERT in Firefox: causes and fixes

> Firefox shows SSL_ERROR_HANDSHAKE_FAILURE_ALERT when the server aborts the TLS handshake. Usually a required client certificate or no common cipher suite.

Source: https://ssl.sh/errors/ssl-error-handshake-failure-alert/
Last updated: 2026-11-10

**SSL_ERROR_HANDSHAKE_FAILURE_ALERT means the server ended the TLS handshake with a `handshake_failure` alert.** Firefox shows "Secure Connection Failed" with "An error occurred during a connection to example.com. SSL peer was unable to negotiate an acceptable set of security parameters." Usually the server wanted a client certificate Firefox did not send, or accepts only cipher suites Firefox no longer offers.

## What the alert means

The server rejected the handshake parameters Firefox offered and did not say which one. TLS servers report fatal problems with numbered alerts. The TLS 1.3 specification, RFC 9846, defines `handshake_failure` (40) as an indication that the sender "was unable to negotiate an acceptable set of security parameters given the options available". NSS, Firefox's TLS library, maps that alert to `SSL_ERROR_HANDSHAKE_FAILURE_ALERT`.

| Firefox code | Who detected the problem |
|---|---|
| `SSL_ERROR_HANDSHAKE_FAILURE_ALERT` | The server, which sent `handshake_failure` |
| [SSL_ERROR_NO_CYPHER_OVERLAP](https://ssl.sh/errors/ssl-error-no-cypher-overlap/) | Firefox, which found no common cipher |
| `SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT` | The server, which sent TLS 1.3 `certificate_required` |
| [SSL_ERROR_UNSUPPORTED_VERSION](https://ssl.sh/errors/ssl-error-unsupported-version/) | Protocol version mismatch |

Chrome reports the same server behaviour as [ERR_SSL_VERSION_OR_CIPHER_MISMATCH](https://ssl.sh/errors/err-ssl-version-or-cipher-mismatch/), or as [ERR_BAD_SSL_CLIENT_AUTH_CERT](https://ssl.sh/errors/err-bad-ssl-client-auth-cert/) when a client certificate is involved.

## Common causes, most frequent first

### 1. The server requires a client certificate

Corporate portals, government services, banking back offices and VPN gateways often require [mutual TLS](https://ssl.sh/learn/mtls/). If Firefox sends no certificate, an OpenSSL-based server configured to require one aborts. In OpenSSL, the TLS 1.3 alert `certificate_required` is translated to `handshake_failure` on TLS 1.2 connections, so on TLS 1.2 you get exactly this error.

Confirm by checking whether the server asks for a certificate:

```bash
openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null 2>/dev/null \
  | sed -n '/Acceptable client certificate CA names/,/Requested Signature/p'
```

A list of CA names means the server requests client certificates. Apache does this with `SSLVerifyClient require`.

On the Firefox side, Firefox 90 and later look for client certificates in the Windows and macOS certificate stores automatically. Certificates on smart cards or USB tokens need the vendor's PKCS#11 module loaded under Settings > Privacy & Security > Security Devices. An expired personal certificate is treated as no certificate.

### 2. The server accepts only legacy cipher suites

Old appliances, embedded web interfaces and unpatched servers may accept only suites that current Firefox no longer offers. Compare what the server accepts with what modern clients send:

```bash
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -brief </dev/null
nmap --script ssl-enum-ciphers -p 443 example.com
```

If only old CBC or 3DES suites appear, the server must be updated. Look up any suite with the [cipher suite lookup](https://ssl.sh/tools/cipher-suite-lookup/).

### 3. Firefox TLS preferences were changed

Hardening guides and some extensions change `security.ssl3.*` or `security.tls.version.*` in `about:config`. If you disabled the suites a server needs, the server answers with this alert. Test in a fresh Firefox profile (`about:profiles` > Create a New Profile). If it works there, reset the changed preferences.

### 4. Security software or a proxy in the middle

Antivirus HTTPS scanning and corporate proxies terminate TLS themselves. If their own outbound configuration is outdated, the upstream server rejects them and the alert is passed on to Firefox. Turning off HTTPS scanning briefly, or trying another network, shows whether this is the cause. See [antivirus HTTPS scanning](https://ssl.sh/errors/antivirus-https-scanning-ssl-error/).

### 5. Hostname not configured on the TLS terminator

Some load balancers and CDNs abort with a generic failure alert when they have no certificate for the requested hostname instead of sending `unrecognized_name`. Run the `openssl s_client` command with and without `-servername` and compare.

## How to fix it

Users install or select the client certificate the site requires; administrators enable modern cipher suites or fix the client-certificate setup.

**Users of a site that needs a personal certificate:**
1. Update Firefox to the current release.
2. Install the certificate in the operating system store, or import the `.p12`/`.pfx` file under Settings > Privacy & Security > Certificates > View Certificates > Your Certificates.
3. For smart cards, load the PKCS#11 module from the card vendor under Security Devices.
4. Reload the page and pick the certificate when Firefox asks.

**Server administrators:**
- Enable TLS 1.2 and 1.3 with ECDHE and AES-GCM or CHACHA20 suites; the [TLS config generator](https://ssl.sh/tools/tls-config-generator/) outputs a tested block.
- If client certificates are optional for some users, use `SSLVerifyClient optional` in Apache or `ssl_verify_client optional;` in Nginx and handle missing certificates in the application, which gives users a readable error page instead of a broken handshake.
- Make sure every hostname has a certificate on every TLS terminator.

## How to verify the fix

1. `openssl s_client -connect example.com:443 -servername example.com -brief` completes and prints the protocol and cipher.
2. For mutual TLS, test with the client certificate: `openssl s_client -connect example.com:443 -servername example.com -cert client.pem -key client.key -brief`.
3. Load the site in Firefox; the [SSL checker](https://ssl.sh/tools/ssl-checker/) confirms the server side looks normal from outside.
