Fix HSTS Preload Error: "You cannot visit this site right now because it uses HSTS"

intermediate๐Ÿ”’ SSL/TLS2026-03-22| Chrome, Firefox, Edge, Safari on Windows, macOS, Linux โ€” any site with HSTS or HSTS Preload enabled

Error Message

You cannot visit this site right now because it uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later.
#ssl#hsts#preload#security

What's Happening

You open a site in your browser and hit a wall:

You cannot visit this site right now because it uses HSTS.
Network errors and attacks are usually temporary, so this page will probably work later.

The browser isn't broken. It's doing exactly what it was told. HSTS (HTTP Strict Transport Security) is a security policy that orders browsers: never connect to this domain over plain HTTP, only HTTPS. Once that instruction is in place โ€” from a previous visit or from the HSTS preload list built into the browser itself โ€” it enforces HTTPS absolutely. Any HTTP request gets killed before it leaves your machine.

This error shows up in two situations:

  • You're a developer who enabled HSTS, then broke HTTPS โ€” expired cert, misconfigured redirect, or local dev running without TLS.
  • You're visiting a domain that either sent a valid HSTS header during a previous session, or is listed in the browser's hardcoded preload list.

Root Cause

HSTS enforcement comes from two completely separate places:

  • Browser HSTS cache: When your browser visits a site sending Strict-Transport-Security headers, it stores that policy locally. Every future visit automatically upgrades HTTP to HTTPS. If HTTPS fails, the browser shows this error โ€” it won't fall back to plain HTTP.
  • Preload list: Chrome, Firefox, Edge, and Safari all ship with a hardcoded list of domains locked to HTTPS. If your domain is on it, even a brand-new browser install blocks HTTP. The list is compiled into the browser binary. Clearing your cache does nothing.

Diagnosing Which Case You're In

Check Chrome's HSTS cache

Open Chrome and go to:

chrome://net-internals/#hsts

Under Query HSTS/PKP domain, type your domain (e.g., example.com) and click Query. A result means Chrome has HSTS cached for that domain.

Look at the static_sts_domain field in the output. If it reads true, the domain is on the preload list. Cache clearing won't help โ€” you're in Fix 3 territory.

Check Firefox's HSTS status

Firefox has no internal page equivalent to Chrome's. The fastest route is hstspreload.org โ€” paste your domain and it tells you immediately whether it's preloaded and in which browsers.

For locally cached HSTS (not preload), clearing Firefox's site preferences removes it. See Fix 1 below.

Fix 1: Clear the Browser HSTS Cache (For Users)

This works only if the domain is not on the preload list. If it is, skip straight to Fix 3.

Chrome

  • Go to chrome://net-internals/#hsts
  • Scroll to Delete domain security policies
  • Enter the domain (e.g., example.com) โ€” no http:// or https://
  • Click Delete
  • Run Query again to confirm โ€” it should return nothing

Firefox

  • Close all tabs for the affected site
  • Open the History menu โ†’ Clear Recent History
  • Set time range to Everything
  • Check Active Logins and Site Preferences
  • Click Clear Now

Site Preferences is what holds HSTS data. Clearing only "Cache" won't touch HSTS records โ€” a common mistake.

Edge

edge://net-internals/#hsts

Same flow as Chrome. Find Delete domain security policies, enter the domain, delete.

Safari (macOS)

Safari provides no UI for this. You have to delete the file directly:

  • Quit Safari completely
  • Delete the HSTS database:
rm ~/Library/Cookies/HSTS.plist
  • Reopen Safari

Fix 2: Fix the Server-Side HSTS Configuration (For Developers)

If you enabled HSTS and now need HTTP access โ€” local dev, domain migration, an expired cert โ€” here's how to unwind it without locking out your own users.

Lower the max-age before removing HSTS

Don't just delete the HSTS header cold. Browsers cache the old policy until max-age expires, so existing visitors stay blocked regardless. Set max-age=0 first so new visitors stop enforcing HSTS as the old caches drain:

# Nginx
add_header Strict-Transport-Security "max-age=0" always;

# Apache
Header always set Strict-Transport-Security "max-age=0"

Wait out the original max-age window โ€” up to 365 days if you set max-age=31536000. Then remove the header entirely.

If your SSL cert expired or HTTPS is broken

Fix HTTPS first. Nothing else matters until that's working. Renew the cert:

# Let's Encrypt / Certbot
sudo certbot renew
sudo systemctl reload nginx

# Verify the cert is valid
curl -I https://yourdomain.com
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates

Local development without HTTPS

Use a different hostname for local dev โ€” don't run the production domain locally. Something like myapp.local sidesteps HSTS entirely. If you actually need HTTPS locally, mkcert generates browser-trusted local certs in under a minute:

mkcert -install
mkcert localhost 127.0.0.1 myapp.local

Fix 3: Remove from HSTS Preload List (Long Process)

Browser cache cleared and still blocked? The domain is on the preload list. Cache clearing is irrelevant here. There's only one exit:

  • Keep HTTPS working. The preload list maintainers won't process a removal request if your HTTPS is broken.
  • Remove the preload directive from your HSTS header:
# Before (has preload)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

# After (remove preload directive)
Strict-Transport-Security: max-age=31536000; includeSubDomains
  • Submit a removal request at hstspreload.org/removal
  • Wait โ€” removal takes months. It requires a Chrome update to actually reach users.

Users on older browser versions stay blocked the entire time. This is permanent-level commitment. Never add preload to a domain you might ever need to walk back to HTTP.

Verification

After applying the fix, run these checks:

# Check current HSTS headers from your server
curl -sI https://yourdomain.com | grep -i strict

# Confirm HTTP redirects properly
curl -sI http://yourdomain.com | grep -i location

# Test the full TLS chain
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

Back in Chrome, go to chrome://net-internals/#hsts and query your domain. A successful cache clear returns nothing. If static_sts_domain: true still appears, the domain is preloaded โ€” the browser cache was never the issue.

Prevention

HSTS is a one-way door. Treat it that way before flipping the switch โ€” especially with preload.

  • Set up SSL cert auto-renewal before enabling HSTS. Certbot's systemd timer handles Let's Encrypt automatically; AWS ACM renews on its own. A dead cert plus HSTS locks users out with no quick escape.
  • Test with a short max-age first โ€” max-age=300 gives you a 5-minute window to catch problems before committing to a year.
  • Never add preload to a domain you might ever need to revert to HTTP. The exit process alone takes months.
  • Monitor cert expiry actively. By the time users report the HSTS error, the cert has already been dead long enough for the damage to spread.

When chasing SSL or HTTPS issues that involve firewall rules and routing, CIDR ranges tend to come up. ToolCraft's Subnet Calculator handles that quickly โ€” runs entirely in the browser, no data sent anywhere.

Lessons Learned

  • HSTS is intentionally hard to undo. Browsers trust the cached policy over whatever the server says right now โ€” that's the whole point of the security model.
  • The preload list is not the browser cache. These are different mechanisms with different fixes. Clearing cache does not remove preload entries.
  • Start with max-age=300 when testing HSTS. Only bump to 1 year โ€” and add preload โ€” when you're fully committed and HTTPS is solid.
  • Inheriting a domain with HSTS problems? Check hstspreload.org immediately. It tells you upfront whether the fix takes hours or months.

Related Error Notes