Deep dive

What Is HSTS and Should You Enable It?

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

1 Without HSTS First request can go out over plain HTTP before any redirect happens 2 Attacker window That brief unencrypted moment is exactly what SSL stripping exploits 3 With HSTS Browser refuses to even attempt HTTP after the first HSTS response 4 Preload list Hardcoded in the browser itself — protects even the very first visit
HSTS removes the unencrypted window an attacker could exploit

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

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

  1. Confirm HTTPS works correctly, with a proper redirect, on the main domain and every subdomain you plan to include.
  2. Set the header with a short max-age first — a day or a week — without includeSubDomains or preload yet, and monitor for any issues.
  3. Extend max-age to a longer window (commonly one year) once you're confident nothing broke.
  4. Add includeSubDomains once every subdomain is confirmed to serve HTTPS correctly.
  5. 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.

The short version: HSTS turns "redirect to HTTPS" into "never even attempt HTTP," closing the specific window that SSL stripping attacks depend on.