HTTP Strict Transport Security (HSTS) is a response header that instructs a browser to only ever connect to your domain over HTTPS — even if a visitor types a plain http:// address, clicks an old bookmark, or follows a link from somewhere that still points to the insecure version.
The gap it closes
Even on a site with a proper server-side HTTPS redirect, there's a brief window on a visitor's very first connection where their browser is still contacting the domain over plain HTTP, before the redirect response comes back. A man-in-the-middle attacker positioned on that network (public Wi-Fi is the classic case) can intercept that first plain-HTTP moment and simply never let the redirect happen — a technique called SSL stripping. HSTS is the direct countermeasure: once a browser has received an HSTS header from your domain once, it will refuse to ever send a plain HTTP request to that domain again for the specified duration, regardless of what a link or bookmark says.
Setting the header
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age— how long (in seconds) the browser should remember to enforce HTTPS-only for this domain; 31536000 is one year, a common starting point.includeSubDomains— extends the policy to every subdomain, not just the exact domain the header was received on.preload— signals intent to be included in the browser-level HSTS preload list (see below).
The remaining gap, and how preload closes it
HSTS as described above only protects a visitor after their first successful HTTPS visit — the very first connection ever made to your domain from a given browser is still theoretically exposed, since the browser has no HSTS policy for your domain yet to enforce. The HSTS preload list solves this by hardcoding a list of domains directly into browser source code itself, so browsers refuse plain HTTP to those domains from the very first connection, with no prior visit required. Submitting your domain requires meeting a few conditions (valid certificate, HTTPS redirect on all subdomains, the header present with preload included) via hstspreload.org.
The trade-off to understand before enabling it
HSTS is a one-way commitment for the duration of max-age: once set, there is no way to serve that domain over plain HTTP again for any visitor who's already received the header, even temporarily, even for a legitimate reason (like an emergency rollback). Preloading is even more permanent — removal from the preload list can take months to propagate across already-shipped browser versions. Start with a shorter max-age while confirming HTTPS is fully stable across every subdomain, then increase it and consider preloading once you're confident.
Should you enable it?
For any site that's fully committed to HTTPS across all subdomains — which, practically, should be nearly every site today — yes, HSTS is a low-effort, meaningful security improvement. The main reason to hold off is if you have subdomains still legitimately served over plain HTTP that you're not ready to migrate yet, since includeSubDomains would break them.
A staged rollout, in practice
- Confirm HTTPS works correctly, with a proper redirect, on the main domain and every subdomain you plan to include.
- Set the header with a short
max-agefirst — a day or a week — withoutincludeSubDomainsorpreloadyet, and monitor for any issues. - Extend
max-ageto a longer window (commonly one year) once you're confident nothing broke. - Add
includeSubDomainsonce every subdomain is confirmed to serve HTTPS correctly. - Consider submitting to the HSTS preload list only after the above has been stable for a meaningful period — this step is close to permanent, so it should be last, not first.
How HSTS interacts with the browser cache, concretely
Once a browser receives a valid HSTS header from your domain, it stores that policy locally, keyed to the domain, independent of cookies or any other site data — clearing cookies or browsing history does not clear a stored HSTS policy; it has its own separate expiry governed purely by max-age counting down from the most recent time the header was received. Each subsequent visit within that window refreshes the timer if the header is still present, which is why a site that's stopped sending the header (for instance, after a botched configuration change) will still be enforced as HTTPS-only for existing visitors until their locally stored policy naturally expires, even though the server itself is no longer actively requesting it.
Mistakes that cause real outages
The most common HSTS mistake is enabling includeSubDomains before actually confirming every subdomain serves valid HTTPS — a forgotten legacy subdomain still on plain HTTP, or one with an expired certificate, becomes completely unreachable for any browser that's already received the header, with no graceful fallback. The second most common mistake is treating max-age as a set-and-forget value without accounting for what happens if you ever need to roll back — because there is no way to un-set HSTS early for browsers that already cached the policy, a rollback effectively has to wait out the remaining max-age window, which is a real operational constraint worth planning for rather than discovering during an incident.
A staged rollout that avoids breaking anything
Rather than enabling HSTS at full strength immediately, a safer sequence is: confirm HTTPS works correctly everywhere first, set a short max-age initially and monitor for issues, then extend the max-age to a full year, and only add includeSubDomains once every subdomain is confirmed to serve valid HTTPS — jumping straight to the strongest settings without this staging is the most common cause of HSTS-related outages.
Why there's no way to quickly undo it once set
Once a browser has received an HSTS header, it will refuse plain HTTP connections to that domain for the remainder of the max-age window, with no way for you to instruct that browser to forget the policy early — this is a deliberate design property, not an oversight, and it's exactly why testing thoroughly before extending max-age to a full year matters so much.
How HSTS interacts with a browser's stored policy, concretely
Once a browser receives a valid HSTS header, it stores that policy locally, independent of cookies or browsing history — clearing cookies doesn't clear a stored HSTS policy. Each visit within the max-age window refreshes the timer if the header is still present, which is why a site that's stopped sending the header will still be enforced as HTTPS-only for existing visitors until their locally stored policy naturally expires.
The specific mistake that causes real outages
The most common HSTS mistake is enabling includeSubDomains before actually confirming every subdomain serves valid HTTPS — a forgotten legacy subdomain still on plain HTTP becomes completely unreachable for any browser that's already received the header, with no graceful fallback available to those visitors.
HSTS is one of the few TLS-adjacent settings that's simultaneously simple to enable and meaningfully closes a real attack path — worth prioritizing once your HTTPS setup is confirmed stable across every subdomain.
A quick closing checklist before enabling HSTS at full strength
Confirm HTTPS works flawlessly across every subdomain, start with a short max-age before extending to a full year, and only add includeSubDomains once every subdomain is individually verified — three steps that prevent the most common HSTS-related outage.