Overview
ERR_SSL_PROTOCOL_ERROR means your browser connected to the site on port 443 but didn’t get a valid TLS handshake back. On hosting servers the cause is usually one of three things: the server answered in plain HTTP on the HTTPS port, the domain’s DNS points at a server that isn’t set up for HTTPS on that name, or something on your side (antivirus, proxy, firewall) broke the connection. One openssl command, run from any computer, tells you which side the problem is on.
Chrome and Edge show it as “This site can’t provide a secure connection. example.com sent an invalid response. ERR_SSL_PROTOCOL_ERROR”. The same fault shows up in Firefox as SSL_ERROR_RX_RECORD_TOO_LONG and in Safari as “Safari can’t establish a secure connection to the server”, so if a visitor reports any of those, this guide applies.
This is for site owners on cPanel or Plesk hosting and anyone running their own VPS. By the end you’ll know exactly where the handshake breaks and how to fix it. If your error is about an expired certificate instead, see SSL certificate not renewing; if the padlock is only broken on some pages, it’s mixed content.
What causes ERR_SSL_PROTOCOL_ERROR
- Plain HTTP on port 443. The web server listens on 443 but isn’t doing TLS there: an Nginx
listen 443;line withoutssl, an Apache<VirtualHost *:443>withoutSSLEngine on, or a firewall or load balancer forwarding 443 to a port that serves HTTP. This is the most common cause on a self-managed VPS. - DNS pointing at the wrong place. An A record still aimed at an old server, or an AAAA (IPv6) record nobody remembers adding. Browsers prefer IPv6 when it’s available, so a stale AAAA record breaks HTTPS for some visitors while it works fine for you.
- Something in between. Antivirus “HTTPS scanning”, a corporate proxy, a captive Wi-Fi portal or a VPN intercepting the connection.
- A broken web server config after a change. A panel update, a hand edit or a failed certificate install that left the HTTPS virtual host half-written.
Two errors look similar but have different causes: ERR_SSL_VERSION_OR_CIPHER_MISMATCH (the server only offers old TLS versions, or has no certificate for the name you asked for) and NET::ERR_CERT_DATE_INVALID (an expired certificate or a wrong clock on your computer). The table at the end of the fixes covers them.
How to fix ERR_SSL_PROTOCOL_ERROR
Fix 1: Test the handshake outside the browser
Run this from your computer’s terminal (macOS, Linux, or Windows with Git Bash or WSL). Replace example.com with your domain in both places:
openssl s_client -connect example.com:443 -servername example.com </dev/null
A healthy site prints the certificate chain and ends with lines like these:
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Verify return code: 0 (ok)
If instead you see wrong version number or packet length too long, the server is speaking plain HTTP on port 443. You can prove it by asking for HTTP on the HTTPS port:
curl -sI http://example.com:443/
If that returns HTTP/1.1 200 OK or any other HTTP status, the server side is broken: go to Fix 2 and Fix 3. If openssl succeeds from your computer but the browser still fails, the problem is on your side: go to Fix 4. I run this test first on every one of these tickets because it cuts the problem in half before touching anything.
Fix 2: Check that DNS points at the right server, including IPv6
dig +short A example.com
dig +short AAAA example.com
dig +short A www.example.com
Compare the results with your hosting account’s IP. In cPanel it’s shown as Shared IP Address in the General Information panel on the right; in Plesk it’s under Websites & Domains > your domain > Hosting & DNS.
- If the A record is wrong, update it in your DNS zone (cPanel Zone Editor guide).
- If there’s an AAAA record and your hosting doesn’t serve the site on IPv6, delete it. This one catches people after a migration: the old host added an IPv6 record, the new server has none, and only visitors on IPv6 networks (most mobile carriers) see the error.
- Test the answer each server gives by running the Fix 1 command against the IP directly:
openssl s_client -connect 203.0.113.10:443 -servername example.com.
DNS changes take time to reach everyone; DNS propagation explains how long and how to check.
Fix 3: Fix the HTTPS virtual host on the server
On cPanel or Plesk hosting you don’t edit web server files yourself. First make sure the domain actually has a certificate: in cPanel open SSL/TLS Status and click Run AutoSSL; in Plesk open SSL/TLS Certificates and issue a Let’s Encrypt certificate. If the openssl test still shows wrong version number after that, the server config needs rebuilding, which is a support ticket on shared hosting. If you manage the server yourself, rebuild the web server config:
# cPanel & WHM (as root)
/scripts/rebuildhttpdconf && /scripts/restartsrv_httpd
# Plesk on Linux (as root)
plesk repair web example.com
If AutoSSL itself is failing, WHM SSL certificate installation failures covers the usual reasons, and on Plesk see how to install an SSL certificate in Plesk.
On a VPS with Nginx, the HTTPS server block must have ssl on the listen line and point at a certificate:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/example.com;
}
On a VPS with Apache (Ubuntu), enable the SSL module and check the 443 virtual host has SSLEngine on with SSLCertificateFile and SSLCertificateKeyFile lines:
sudo a2enmod ssl
sudo apachectl configtest
Always test before reloading, then reload and repeat the Fix 1 test:
sudo nginx -t && sudo systemctl reload nginx
# or for Apache
sudo apachectl configtest && sudo systemctl reload apache2
Also check nothing else has grabbed port 443. sudo ss -tlnp | grep ':443' should show only your web server. Once HTTPS works, redirect HTTP to HTTPS so every visitor lands on the secure version.
Fix 4: Rule out your own computer and network
If the server test passed, the error is local. Work through these in order and retest after each:
- Try another network. Load the site on your phone with Wi-Fi turned off. If it works there, your office network, proxy or router is interfering.
- Turn off HTTPS scanning in your antivirus (often called “Web Shield”, “HTTPS scanning” or “SSL inspection”) and test again.
- Check the date and time on your computer. A wrong clock usually gives a certificate date error, but it can also break the handshake.
- Clear cached connections. In Chrome open
chrome://net-internals/#socketsand click Flush socket pools. On Windows also open Internet Options > Content > Clear SSL state. - Test in an incognito window with extensions off. Security and VPN extensions are a regular cause.
Fix 5: Check the proxy, CDN or load balancer in front
If the site sits behind a CDN, reverse proxy or load balancer, test the origin server directly by IP (Fix 2, last bullet) and then through the proxy. A proxy that is set to send HTTPS traffic to an origin port that only serves HTTP, or the other way round, produces exactly this error. Make the proxy’s origin setting match what the origin really serves on each port.
Related errors and where to look
| Browser error | Usually means | Fix |
|---|---|---|
ERR_SSL_VERSION_OR_CIPHER_MISMATCH |
Server offers only TLS 1.0/1.1, or has no certificate for that name | Fix 3: enable TLS 1.2 and 1.3, install a certificate for the name |
NET::ERR_CERT_DATE_INVALID |
Expired certificate or wrong local clock | Renewal fixes |
NET::ERR_CERT_COMMON_NAME_INVALID |
Certificate doesn’t cover that hostname (often www or a subdomain) | Reissue with both names, or a wildcard certificate |
How to prevent it
- Test with openssl after every server change, not just the browser. Browsers cache connections and can hide a broken config for hours.
- Clean up DNS when you move servers. Check A, AAAA and www records on the day you switch, and delete any AAAA record your new server doesn’t answer on.
- Let the panel manage virtual hosts. On cPanel and Plesk, hand edits to generated config files get overwritten or half-applied. Use the panel’s include files or settings instead.
- Always run
nginx -torapachectl configtestbefore a reload. A failed reload can leave the old, broken config running. - Keep TLS 1.2 and 1.3 enabled and older versions off, so modern browsers always have a protocol in common with the server.
If you’d rather not manage web server config yourself, a cPanel shared hosting plan includes AutoSSL certificates that are installed and renewed for every domain on the account.
Frequently Asked Questions
What does ERR_SSL_PROTOCOL_ERROR mean?
It means the browser connected to the site’s HTTPS port but the reply wasn’t a valid TLS handshake, so no secure connection could be set up. Most often the server is sending plain HTTP on port 443 or DNS points at a server that isn’t configured for HTTPS on that domain.
Is ERR_SSL_PROTOCOL_ERROR caused by my computer or the website?
Run openssl s_client -connect example.com:443 -servername example.com or load the site on your phone using mobile data. If either works, the problem is on your computer or network (antivirus HTTPS scanning, a proxy or an extension). If both fail, the website’s server or DNS is at fault.
Why does the site work for me but show ERR_SSL_PROTOCOL_ERROR for others?
The usual reason is DNS: an old A record or an IPv6 (AAAA) record points some visitors at a different server. Visitors on IPv6 networks, which includes most mobile carriers, reach that address first. Check the A and AAAA records and remove any that point at the wrong server.
How do I fix ERR_SSL_PROTOCOL_ERROR on localhost?
Your local development server is almost certainly serving plain HTTP, so open it with http:// instead of https://. If Chrome keeps forcing HTTPS, go to chrome://net-internals/#hsts and delete the HSTS entry for localhost, or set up a local certificate if you really need HTTPS.
Can an expired SSL certificate cause ERR_SSL_PROTOCOL_ERROR?
Not normally. An expired certificate gives NET::ERR_CERT_DATE_INVALID, which is a different error with a different fix. ERR_SSL_PROTOCOL_ERROR means the handshake failed before the certificate was even checked.