Quick answer for advanced users
Check TLS version support on both sides, update OpenSSL or Schannel, fix the certificate chain, and sync system time. That's the 90% fix.
Why this happens
SSL handshake failure is one of those errors that looks scary but is usually something simple. The client and server just can't agree on how to talk securely. Most of the time it's a TLS version mismatch—the server requires TLS 1.2 but your client only speaks TLS 1.0. Or the certificate chain is broken, or the system time is wrong (I had a client last month whose server clock was off by 3 hours—took me an hour to find it). Another common one is the server doesn't have the intermediate certificates installed. You'll see this in browsers, curl, Python requests, or any app doing HTTPS.
Step-by-step fix
- Check the error message. Look for the exact code.
SSL_ERROR_HANDSHAKE_FAILURE_ALERTis common in Firefox. In Chrome you might seeERR_SSL_PROTOCOL_ERROR. In curl you'll get(35) SSL connection error. Write it down. - Check TLS versions. Use
openssl s_client -connect host:port -tls1_2on Linux. On Windows, useTest-NetConnection host -portand then check Schannel logs in Event Viewer. If it fails with TLS 1.2 but works with TLS 1.0, the server is ancient. If it fails with TLS 1.0 but works with 1.2, your client is outdated. - Fix the certificate chain. Run
openssl s_client -connect host:port -showcerts. Look forverify error:num=20:unable to get local issuer certificate. That means the server didn't send intermediate certs. You need to install them on the server. Most control panels (cPanel, Plesk) have a 'Auto-Fill' button for this. - Check system time. On Windows, look at the clock in the bottom right. On Linux, run
date. If it's off by more than a few minutes, SSL certs will fail. Fix withsudo ntpdate pool.ntp.orgon Linux or enable 'Set time automatically' on Windows. - Update your software. OpenSSL 1.0.2 is dead. Windows 7 without updates won't support modern ciphers. Update to the latest stable versions. On Ubuntu,
sudo apt update && sudo apt upgrade openssl. On Windows, run Windows Update.
Alternative fixes if the main one fails
Client-side fixes
- Clear your SSL cache. In Chrome, go to
chrome://settings/clearBrowserDataand check 'Cached images and files'. In Firefox, go to Preferences > Privacy & Security > Certificates > Clear. - Disable antivirus SSL scanning temporarily. Bitdefender and Avast sometimes break handshakes. I've seen it happen.
- Add the host to the trusted certificate store manually. Export the server cert and import it into your system's trusted roots. Not recommended for long-term but works as a test.
Server-side fixes
- Check the server's SSL configuration. On Apache, look at
/etc/apache2/sites-available/default-ssl.conf. On Nginx, look at/etc/nginx/sites-enabled/default. Make sure you haveSSLProtocol all -SSLv3 -TLSv1 -TLSv1.1to allow TLS 1.2 and 1.3. - Restart the web server:
sudo systemctl restart apache2orsudo systemctl restart nginx. - Use a tool like SSL Labs to check your server publicly. It will tell you exactly what's wrong.
Prevention tip
Set up automatic certificate renewal with Let's Encrypt. Use certbot with cron or a systemd timer. Keep your system time synced with NTP. And test your SSL config with openssl s_client after every change. I do this as part of my deployment checklist. Saves hours of debugging later.