You type in your domain, hit enter, and instead of your site you get a wall of red: ERR_SSL_PROTOCOL_ERROR in Chrome, or SSL_ERROR_RX_RECORD_TOO_LONG in Firefox. There's no "proceed anyway" button like a normal certificate warning — the connection just refuses to happen. If plain http:// loads fine but https:// won't, this is almost never a broken certificate. It's usually port 443 not speaking TLS at all.
Symptom: What You're Actually Seeing
A quick way to tell this apart from a normal SSL warning: certificate problems (expired, wrong domain, untrusted issuer) still let the browser show you a warning screen with details about the cert. ERR_SSL_PROTOCOL_ERROR means the browser opened a TLS handshake on port 443 and got back something that isn't TLS at all — often a plain HTTP response, or nothing coherent. That's a configuration problem, not a trust problem.
Common triggers we see on cPanel and VPS accounts:
- A domain or addon domain with no SSL vhost configured on port 443
- AutoSSL failed to issue (domain validation failed) so there's no cert to serve, but something is still linking to
https:// - Cloudflare's SSL/TLS mode fighting with the origin's actual TLS setup
- A reverse proxy (Nginx in front of Apache, or a Node/PM2 app) listening on 443 without actually terminating TLS
- Testing against the wrong port, e.g. an app bound to 8443 or 3000 with no cert at all
Step 1: Confirm There's No TLS Handshake Happening
Before touching any config, check what's actually answering on 443:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
If this hangs, drops the connection, or prints something like wrong version number, you've confirmed port 443 isn't doing TLS for that hostname — either nothing is listening there for this vhost, or it's answering with plain HTTP. Compare that against:
curl -vI https://yourdomain.com
Look at the "SSL connection using" line. If curl gets further than the browser (or fails the same way), you've narrowed it to the server, not the client.
Cause 1: No SSL Certificate Installed for This Specific Domain
This is the most common cause on shared cPanel hosting, especially for addon domains added after the main account's cert was issued. AutoSSL runs per-domain, and if it hasn't caught up yet (or failed validation for that one hostname), Apache has no SSL vhost for it — so port 443 either serves the default catch-all site or nothing.
Check it in cPanel under Security > SSL/TLS Status. Every domain and subdomain on the account should show a green "Valid" cert with an expiry date. Anything showing "Not Secured" or an old self-signed cert is your answer. From WHM (if you have root), SSL/TLS Status lets you run AutoSSL manually for the whole account and shows the validation log if it's failing.
Cause 2: AutoSSL Validation Is Failing Silently
AutoSSL (Let's Encrypt under the hood) validates domain ownership over HTTP before issuing a cert. That validation fails quietly if:
| Reason validation fails | How to check |
|---|---|
| Domain doesn't resolve to this server yet | dig yourdomain.com +short should return this server's IP |
| A CAA DNS record blocks Let's Encrypt | dig CAA yourdomain.com — if present, it must allow letsencrypt.org |
| Port 80 is firewalled or redirected before validation completes | curl -I http://yourdomain.com/.well-known/acme-challenge/test should reach this server, not bounce elsewhere |
| Cloudflare is proxying (orange cloud) and interfering with the HTTP validation request | Temporarily set the DNS record to "DNS only" (grey cloud), rerun AutoSSL, then re-enable proxying |
Fix whichever one applies, then trigger AutoSSL again from WHM > SSL/TLS Status > Run AutoSSL, rather than waiting for the next scheduled run.
Cause 3: Cloudflare SSL Mode Mismatch
If the domain is proxied through Cloudflare, the SSL/TLS encryption mode under SSL/TLS > Overview has to match what your origin server can actually do:
- Flexible means Cloudflare talks HTTPS to the visitor but plain HTTP to your origin. If your server or a WordPress plugin then force-redirects that incoming HTTP request back to HTTPS, you get a redirect loop that some browsers surface as a protocol error rather than "too many redirects."
- Full or Full (strict) require a real certificate on the origin — if AutoSSL hasn't issued one yet (see Cause 2), Cloudflare can't complete its side of the handshake either, and visitors see a generic SSL error.
The fix order matters: get a valid cert installed and working directly against the origin IP first (bypass Cloudflare by editing your local hosts file to test), then switch Cloudflare to Full (strict). Don't leave it on Flexible long-term once you have a real cert — it's the setting most likely to cause this exact error.
Cause 4: A Reverse Proxy Not Actually Terminating TLS
On a VPS running Nginx in front of Apache, or in front of a Node.js/PM2 app, it's easy to bind port 443 in the Nginx server block without adding the ssl_certificate directives — Nginx will happily listen on 443 and pass through plain traffic, which looks identical to "no TLS" from the browser's side. Check:
nginx -T | grep -A5 "listen 443"
Every listen 443 block needs ssl_certificate and ssl_certificate_key lines pointing at real, existing files, plus the ssl parameter on the listen directive itself (or a separate listen 443 ssl; line on newer Nginx versions that split it out).
Putting It Together
Work through it in this order and you'll rarely need more than two checks:
- Run
openssl s_clientagainst the domain to confirm TLS isn't answering - Check cPanel SSL/TLS Status (or the web server config on a VPS) for a valid cert on that exact hostname
- If behind Cloudflare, verify the SSL mode matches the origin's actual cert state
- Reissue/rerun AutoSSL or Certbot once the underlying blocker (DNS, CAA, port 80 access) is cleared
- Reload the web server (
systemctl reload httpdornginx -s reload) — a cert install without a reload doesn't take effect
Prevention
Most cases of this come from a domain slipping through the cracks after it's added — an addon domain, a new subdomain, or a site pointed at SkyServer before DNS fully propagated. Check SSL/TLS Status right after adding any new domain instead of assuming AutoSSL caught it automatically, and keep an eye on the AutoSSL expiry/renewal emails cPanel sends — they're your earliest warning that a domain's cert isn't renewing cleanly.
Frequently Asked Questions
How is this different from a normal "your connection is not private" warning?
A certificate warning means the browser found a cert but doesn't trust it (expired, wrong hostname, unknown issuer) — you can usually click through to proceed. ERR_SSL_PROTOCOL_ERROR means there's no valid TLS handshake at all, so there's nothing to click through; the connection fails before a certificate is even evaluated.
Why does http:// work but https:// doesn't?
Because the web server has a working vhost on port 80 but either no vhost, no certificate, or a misconfigured listener on port 443 for that specific hostname. It's almost always scoped to one domain, not the whole server.
I just installed a new SSL certificate — why is it still happening?
The web server usually needs a reload or restart to pick up a newly installed certificate. On cPanel this normally happens automatically after AutoSSL runs, but on a VPS where you installed a cert manually, run systemctl reload httpd or nginx -s reload and test again.
My site is behind Cloudflare — is this my server's fault or Cloudflare's?
Almost always the origin. Cloudflare can't serve a valid handshake to visitors if your server doesn't have a working cert for the SSL mode you've chosen. Confirm the origin works with a direct hosts-file test before assuming Cloudflare is misconfigured.
Do I need to clear my browser cache to test a fix?
Not usually for this error, since it's a connection-level failure rather than a cached redirect or HSTS policy. If you've recently changed Cloudflare's SSL mode or forced HTTPS redirects, test in a private/incognito window first to rule out HSTS caching from a previous visit.
