Fix ERR_SSL_PROTOCOL_ERROR on Chrome When Accessing HTTPS Sites

intermediate๐Ÿ”’ SSL/TLS2026-05-15| Google Chrome (all versions), Windows 10/11, macOS, Linux, Ubuntu 20.04/22.04, Nginx 1.18+, Apache 2.4+

Error Message

ERR_SSL_PROTOCOL_ERROR
#chrome#ssl#https#nginx#apache#browser

What You're Seeing

You open Chrome and try to load an HTTPS site. Instead of a page, you get a blank screen:

ERR_SSL_PROTOCOL_ERROR

Sometimes it reads This site can't provide a secure connection. No certificate warning, no partial load โ€” just a hard stop.

The handshake started but never finished. Chrome tried to negotiate a secure TLS connection and the server (or something in between) didn't respond as expected. The culprit could be your browser, your network, or the server itself.

Root Causes

  • Port 443 is listening but SSL isn't configured โ€” the server is serving plain HTTP on an HTTPS port
  • Misconfigured SSL certificate on Nginx or Apache
  • Outdated TLS version forced on the server (SSLv3, TLS 1.0 โ€” Chrome 84+ refuses these)
  • System clock is wrong โ€” Chrome rejects certs if timestamps are off by more than a few minutes
  • Chrome's SSL state cache has gone stale
  • A firewall, proxy, or antivirus is intercepting HTTPS traffic and bungling the handshake
  • Self-signed certificate that Chrome hasn't been told to trust

Quick Triage: Is It Your Machine or the Server?

Don't jump into server configs yet. First, figure out where the problem actually lives:

  • Try the URL in Firefox or Edge โ€” if it loads fine, the issue is Chrome-specific
  • Switch to a phone hotspot and try again โ€” if that works, your network (firewall or proxy) is the suspect
  • Test the SSL handshake from the terminal:
curl -vI https://yourdomain.com 2>&1 | grep -E "SSL|TLS|error|certificate"

Or go straight to OpenSSL:

openssl s_client -connect yourdomain.com:443 -tls1_2

OpenSSL fails too? The problem is on the server. OpenSSL succeeds but Chrome still errors? Look at Chrome settings and local factors first.

Fix 1: Clear Chrome's SSL State Cache

Chrome caches SSL session data to speed up repeat visits. A stale or corrupted cache can trigger ERR_SSL_PROTOCOL_ERROR even on a perfectly valid certificate.

  • Go to chrome://settings/
  • Search for Clear browsing data โ†’ Advanced tab
  • Check Cached images and files and Cookies and other site data
  • Click Clear data

On Windows, also clear the OS-level SSL state:

# Windows: Internet Options โ†’ Content tab โ†’ Clear SSL state
Start โ†’ Run โ†’ inetcpl.cpl โ†’ Content โ†’ Clear SSL state

One more place to check โ€” Chrome's HSTS cache. Visit:

chrome://net-internals/#hsts

Type your domain under Delete domain security policies and hit Delete.

Fix 2: Sync Your System Clock

SSL certificates have a "not before" and "not after" date. If your system clock is off by even 10โ€“15 minutes, Chrome will reject the handshake outright.

# Linux / Ubuntu
timedatectl status
sudo timedatectl set-ntp true

# Or sync manually
sudo ntpdate -u pool.ntp.org

Windows: right-click the clock โ†’ Adjust date/time โ†’ Sync now.

Fix 3: Fix Nginx SSL Configuration

Running the server yourself? This is the most common cause. Forgetting the ssl keyword on the listen directive โ€” or pointing to the wrong certificate path โ€” produces this exact error.

Validate your config first:

sudo nginx -t

A correct HTTPS server block looks like 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;

    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        root /var/www/html;
        index index.html;
    }
}

Three mistakes that reliably produce ERR_SSL_PROTOCOL_ERROR:

  • listen 443 without the ssl keyword โ€” Nginx serves plain HTTP on port 443, Chrome can't negotiate TLS
  • Wrong certificate path โ€” Nginx starts without error but the handshake fails silently
  • Only TLSv1 or TLSv1.1 in ssl_protocols โ€” Chrome 84+ dropped support for both

Reload after fixing:

sudo nginx -t && sudo systemctl reload nginx

Fix 4: Fix Apache SSL Configuration

Apache needs mod_ssl enabled and a properly structured VirtualHost. Start there:

# Enable SSL module if not already active
sudo a2enmod ssl
sudo systemctl restart apache2

A working SSL VirtualHost:

<VirtualHost *:443>
    ServerName yourdomain.com
    DocumentRoot /var/www/html

    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

    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          HIGH:!aNULL:!MD5
</VirtualHost>
sudo apachectl configtest && sudo systemctl reload apache2

Fix 5: Renew an Expired Certificate

Let's Encrypt certs expire every 90 days. Check the current status:

sudo certbot certificates

Expired or within a week of expiry? Force a renewal:

sudo certbot renew --force-renewal
sudo systemctl reload nginx   # or apache2

Fix 6: Disable Antivirus HTTPS Scanning

Avast, Kaspersky, ESET, and similar tools can intercept HTTPS connections and substitute their own certificate. Chrome sees an unexpected cert and kills the handshake.

Turn off HTTPS scanning temporarily and reload the page. Fixed? Re-enable it and add the domain as an exception โ€” don't leave HTTPS inspection permanently off.

Fix 7: Clear HSTS for the Domain

Sites can instruct Chrome to always use HTTPS via HSTS headers. If the cert is now broken on a site that previously enforced HSTS, Chrome won't even attempt an HTTP fallback. Delete the stored policy:

  • Go to chrome://net-internals/#hsts
  • Under Delete domain security policies, type the domain
  • Click Delete

Verification

Once you've applied a fix, confirm the handshake actually works:

# Test TLS handshake
openssl s_client -connect yourdomain.com:443 -tls1_2

# Check certificate validity dates
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

# Full SSL audit
curl -vI https://yourdomain.com 2>&1 | head -40

In Chrome, click the lock icon โ†’ Connection is secure โ†’ Certificate is valid. If you see that, you're done.

Still Not Working?

Exhausted the common fixes? A few less obvious culprits:

  • Port 443 blocked at the firewall: sudo ufw status or sudo firewall-cmd --list-ports
  • Domain resolving to the wrong IP: dig yourdomain.com +short
  • Certificate issued for a different domain โ€” wildcard vs. subdomain mismatches are easy to miss
  • Deep SSL debugging: launch Chrome with chrome --ssl-key-log-file=/tmp/ssl.log and analyze the capture in Wireshark

Related Error Notes