The Error
Firefox shows a blank page with:
SSL_ERROR_NO_CYPHER_OVERLAP
Translation: Firefox tried to shake hands with the server, but they couldn't agree on a single cipher suite. The server is either pushing ciphers Firefox blacklisted years ago, or its cipher list is broken entirely.
Root Cause
Four things cause this, and the first one covers 80% of cases:
- Server only accepts TLS 1.0 or TLS 1.1 โ Firefox 78+ (released June 2020) killed support for both.
- The
ssl_ciphers(Nginx) orSSLCipherSuite(Apache) directive only lists RC4, DES, or export-grade ciphers Firefox removed long ago. - Someone copy-pasted an SSL config from a 2014 Stack Overflow answer without checking if those ciphers still exist.
- A custom cipher string that looks reasonable but accidentally excludes everything modern Firefox supports.
Chrome loads the same site without complaint because it still accepts some legacy ciphers. Firefox doesn't. That's a feature, not a bug.
Diagnose First
Don't touch configs yet. Find out what the server is actually advertising:
# Test each TLS version individually
openssl s_client -connect yourdomain.com:443 -tls1
openssl s_client -connect yourdomain.com:443 -tls1_1
openssl s_client -connect yourdomain.com:443 -tls1_2
openssl s_client -connect yourdomain.com:443 -tls1_3
# Full cipher list with grades
nmap --script ssl-enum-ciphers -p 443 yourdomain.com
TLS 1.0/1.1 connects but TLS 1.2 fails? That's your culprit. Cipher list shows only RC4 or DES variants? Same problem, different angle.
Fix 1: Update Nginx SSL Config
Covers 90% of cases. Open your server block:
sudo nano /etc/nginx/sites-available/yourdomain.conf
# or
sudo nano /etc/nginx/conf.d/yourdomain.conf
Replace the SSL section with this:
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# TLS 1.0 and 1.1 are dead โ don't serve them
ssl_protocols TLSv1.2 TLSv1.3;
# Modern cipher suite โ all supported by Firefox 78+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Session cache โ reduces handshake overhead for repeat visitors
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
}
Test and reload:
sudo nginx -t
sudo systemctl reload nginx
Fix 2: Update Apache SSL Config
Find your SSL virtualhost โ usually in /etc/apache2/sites-available/ or /etc/httpd/conf.d/ssl.conf:
sudo nano /etc/apache2/sites-available/yourdomain-ssl.conf
Update these directives:
<VirtualHost *:443>
ServerName yourdomain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem
# Strip old protocol versions
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
# Modern ciphers only
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
</VirtualHost>
Test and restart:
sudo apachectl configtest
sudo systemctl reload apache2
# RHEL/CentOS:
sudo systemctl reload httpd
Fix 3: Legacy Clients That Only Speak TLS 1.0
Rare, but it happens โ old IoT devices, embedded systems, or internal tools locked to TLS 1.0. You can re-enable it temporarily in Firefox while you sort out the server:
- Type
about:configin the address bar - Accept the warning
- Search for
security.tls.version.min - Change
3(TLS 1.2) to1(TLS 1.0)
Workaround only โ not a solution. TLS 1.0 has known practical attacks (BEAST, POODLE). Fix the server. Revert this setting when you're done.
Fix 4: Conflicting ssl_ciphers in nginx.conf
A sneaky one. A global ssl_ciphers in /etc/nginx/nginx.conf can silently override what you set in the server block. Scan for conflicts:
grep -rn "ssl_ciphers\|ssl_protocols" /etc/nginx/
Multiple files with different values? Consolidate. Pull everything into a shared snippet:
# /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers off;
Then each server block just says:
include snippets/ssl-params.conf;
One source of truth, no surprises.
Verify the Fix
After reloading, run these to confirm:
# TLS 1.2 should succeed
openssl s_client -connect yourdomain.com:443 -tls1_2 2>&1 | grep -E "Protocol|Cipher"
# Expected:
# Protocol : TLSv1.2
# Cipher : ECDHE-RSA-AES256-GCM-SHA384
# TLS 1.3 should also work
openssl s_client -connect yourdomain.com:443 -tls1_3 2>&1 | grep -E "Protocol|Cipher"
# TLS 1.1 must be rejected
openssl s_client -connect yourdomain.com:443 -tls1_1 2>&1 | grep -i "error\|alert"
Run it through SSL Labs too โ a proper config gets an A. Still seeing SSL_ERROR_NO_CYPHER_OVERLAP after all this? Clear Firefox's SSL state cache: about:preferences#privacy โ Clear Data โ Cached Web Content.
Prevention
- Mozilla's SSL Configuration Generator (ssl-config.mozilla.org) produces ready-to-paste Nginx/Apache configs. It tracks current recommendations automatically โ use it instead of writing cipher strings by hand.
- Run SSL Labs as part of your deploy process. Five minutes per release beats explaining to users why Firefox won't load your site.
- Audit your SSL config once a year. Cipher recommendations moved significantly between 2018 and 2024 โ what passed then may not pass now.
- Using Let's Encrypt with Certbot? Run
sudo certbot renew --dry-runand double-check your Nginx/Apache config afterward. Certbot sometimes touches ssl directives during renewal.

