You submitted your domain to hstspreload.org because the security checklist said to. A few weeks later it shipped in Chrome and Firefox. Now you need to roll back — maybe you’re selling the domain, maybe your cert provider failed and you need temporary HTTP, maybe you’re decommissioning. You remove the Strict-Transport-Security header. You set max-age=0. Doesn’t matter. Browsers continue to enforce HTTPS for your domain and every subdomain (because you set includeSubDomains, as required for preload). This is by design: preload bakes your domain into the browser binary itself. The fix path is real but slow — measured in months, not minutes — and the “site works only over HTTPS” constraint is much stricter than people realize before submitting.
Common causes
What landed you here, ordered by how often each shows up in postmortems.
1. Subdomain you forgot about now needs HTTP
You submitted preload covering includeSubDomains. Months later someone spins up legacy.yourdomain.com on a service that only does HTTP (an old IoT panel, a printer admin, a CI artifact server). Browsers refuse to load it ever, because the parent’s preload forces HTTPS on everything under it.
How to spot it: New subdomain returns ERR_SSL_PROTOCOL_ERROR or “This site can’t be reached” in Chrome before the user even types http:// — Chrome upgrades to HTTPS first.
2. Cert expired and you can’t issue a new one fast
Your cert expired. You have HTTPS broken on the origin. Users get NET::ERR_CERT_DATE_INVALID with no “proceed anyway” option because preload sets the strict bit. There is no clickthrough for preloaded domains.
How to spot it: Cert is expired AND chrome://net-internals/#hsts shows your domain as static. No bypass.
3. Domain ownership transferred, new owner needs HTTP
You sold or released the domain. New owner inherits the preload entry — they cannot host plain HTTP for any subdomain until removed from the list AND browser caches age out.
How to spot it: New owner’s deploy works on a different domain but breaks the moment they point yourdomain.com at it without HTTPS.
4. Self-signed or internal CA cert can no longer be accepted
Pre-preload, users could click through cert warnings for an internal staging server. Post-preload, no clickthrough is possible. Internal QA team is locked out of staging.
How to spot it: Internal staging at staging.yourdomain.com shows NET::ERR_CERT_AUTHORITY_INVALID with no bypass option after preload landed.
5. Captive portal / public Wi-Fi can’t intercept
Some captive portals work by intercepting HTTP requests. Users on your preloaded domain can’t sign in through hotel/airport Wi-Fi because the browser refuses any HTTP-level redirect for your domain. Connectivity feels broken even when basic Wi-Fi works.
How to spot it: Users report site fails on hotel/airport Wi-Fi but works elsewhere. Other non-preloaded sites work.
6. Wildcard cert mistakes amplify because no fallback
Without preload, a misconfigured wildcard at least shows users a cert warning they could bypass for troubleshooting. With preload, every misconfig is a hard fail with no clickthrough — small mistakes become outages.
How to spot it: Any cert mismatch on a preloaded domain = hard NET::ERR_CERT_COMMON_NAME_INVALID with no bypass.
Before you start
- Confirm the domain is actually preloaded: visit
https://hstspreload.org/?domain=yourdomain.com. - Know which browsers your users actually use — Chrome, Firefox, Safari all carry their own preload lists with different update cadences.
- Have your current SSL cert state documented (expiry, issuer, chain).
- Decide if your need is “rollback permanently” or “tolerate HTTPS for the foreseeable future and just fix the cert”.
Information to collect
- Output of
curl -I https://yourdomain.com— is the HSTS header still being sent? - Browser DevTools → application/storage → check
chrome://net-internals/#hstsfor your domain. - The original max-age and includeSubDomains values from your nginx / app config.
- A list of all subdomains currently in use and whether each can serve valid HTTPS.
- An estimate of how many users are blocked / inconvenienced right now.
Step-by-step fix
The honest order: short path = restore HTTPS; long path = removal from preload list.
Step 1: First check, can you just restore HTTPS?
90% of “HSTS preload stuck” tickets are really “cert expired and we panicked”. Fix the cert.
sudo certbot renew --force-renewal
sudo systemctl reload nginx
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates
If you can get a valid cert back, your problem is gone. You don’t need to remove preload at all.
Step 2: For internal staging needing self-signed certs, use a non-preloaded domain
The cleanest fix is to NOT use a subdomain of your preloaded domain for internal/self-signed work. Move staging to staging.yourdomain-internal.com or similar — an entirely separate registration not on the preload list.
If you must keep the subdomain on the preloaded parent, install a real cert (Let’s Encrypt + DNS-01 challenge works for internal-only domains, since you don’t need public HTTP).
Step 3: Send max-age=0 immediately, even though it only helps non-preloaded clients
Update your HTTPS response:
add_header Strict-Transport-Security "max-age=0; includeSubDomains" always;
Reload nginx. This causes any browser that has visited your site via HTTPS (with the dynamic HSTS cache) to forget. It does NOT help with the preload list — those entries are baked into the browser binary — but it is a prerequisite for being removed from the list.
Step 4: Submit removal request at hstspreload.org
Visit https://hstspreload.org/removal/. Enter your domain. The site checks:
- Your domain is currently sending
max-age=0over HTTPS (or no HSTS header). - The check passes for the apex.
If both pass, your domain gets queued for removal. Removal lands in:
- Chrome: next release cycle (~6 weeks), then ~6 months for full rollout to stable channel.
- Firefox: similar cadence.
- Safari / WebKit: separate process, often longer.
Realistic timeline: 6-12 months before any meaningful percentage of users no longer have your domain preloaded. Plan accordingly.
Step 5: For affected users right now, document workarounds
Users with the preloaded browser cache cannot easily bypass. Real workarounds:
- Use Firefox if Chrome is blocked (or vice versa) — preload lists differ slightly.
- Use a different browser (Brave, Vivaldi inherit Chrome’s list; Edge too).
- For internal users, deploy a real cert immediately — even Cloudflare’s free edge cert works in minutes if you put the domain behind Cloudflare proxy.
- For developers debugging,
chrome://net-internals/#hsts→ “Delete domain security policies” removes the DYNAMIC entry but not the static preload. Limited utility but worth trying.
Step 6: Permanent rollback only if truly necessary
If you must permanently roll back (selling domain, decommissioning):
- Submit removal at
hstspreload.org/removal/. - Wait for the next major Chrome / Firefox release that includes the removal (~6 weeks build + ~3-6 months distribution).
- Accept that users on old browser versions will continue to enforce HTTPS for years.
- Communicate the constraint to whoever takes over the domain — they cannot run HTTP on it for the long tail of installed browsers.
Verify
https://hstspreload.org/?domain=yourdomain.comsays “not preloaded” (after removal lands).curl -I https://yourdomain.comreturns nostrict-transport-securityheader (ormax-age=0).- In
chrome://net-internals/#hstsyour domain query returns “not found” for static entries (after removal ships in Chrome). - New subdomains on your apex can serve HTTP without browser intervention (only after removal AND user’s browser updated).
Long-term prevention
- Treat
hstspreload.orgsubmission as a one-way door. Do NOT submit unless you can guarantee HTTPS-only for ALL subdomains, forever, with a tested cert renewal pipeline. - Use
max-age=of 6 months on the header in production without submitting to preload, until you have a year of clean HTTPS uptime — then consider preload. - Never submit a wildcard or internal-services domain to preload. Keep preload for the public marketing domain only.
- Have cert-expiry monitoring 25+ days ahead of expiry, not 7. Preload makes cert lapses much more painful.
- Document the preload constraint in your DNS-as-code repo so future engineers don’t accidentally point a non-HTTPS service at a subdomain.
Common pitfalls
- Removing the HSTS header from nginx config and assuming the problem is solved — preload is in browser binaries, not your server.
- Submitting to preload “for the security score” without understanding the irreversibility — most security teams will accept a 6-month
max-agefor the same compliance benefit. - Trying to bypass preload in production browsers — there is no consumer-facing bypass. Telling users “type
thisisunsafe” only works on the cert-error interstitial, not for preload’s lack-of-clickthrough. - Putting a sub-product on a subdomain of a preloaded parent and being surprised when self-signed certs are unusable.
- Submitting removal and assuming it lands tomorrow — it ships with the next browser version, not on demand.
FAQ
Q: How long until removal actually takes effect for real users?
Submission to removal in the GitHub repo takes weeks. The next Chrome/Firefox stable that includes the removal lands ~6 weeks later. Then 3-6 months for the user base to update. Realistic window: 6-12 months. Some users on old browsers may never get the removal.
Q: Can I just delete the cookie / cache in Chrome to bypass?
You can bypass DYNAMIC HSTS entries (entries set by your server’s header) via chrome://net-internals/#hsts. You CANNOT bypass static preload entries — those are compiled into the browser. Use a different browser as the only real workaround.
Q: Is there a “soft preload” with max-age?
Yes — setting Strict-Transport-Security: max-age=15552000; includeSubDomains (6 months) without preload submission gives 95% of the security benefit without the irreversibility. Most compliance frameworks accept this.
Q: My security scanner says I lose points for not being preloaded. Should I submit?
If your scanner is rigid, push back with the rationale that preload is a one-way door and operational risk outweighs the marginal security gain over a long max-age. Most modern frameworks (NIST, CIS) accept this distinction.
Related: SSL cert delay, HTTPS not forced, SSL mixed content warning, redirects broken after domain change.
Tags: #Troubleshooting #SSL #https #hsts #Security