Security May 17, 2026 6 min read

HTTP Strict Transport Security Explained: HSTS Deep Dive

HTTP Strict Transport Security explained with real headers, preload rules, common misconfigurations, and how to verify HSTS is actually working on your site.

If your site supports HTTPS but still answers on port 80, you have a problem that a redirect alone won't fix. The first request a browser sends is plain HTTP, and anyone on the network path can intercept it before the redirect happens. HTTP Strict Transport Security (HSTS) is the header that closes that window — it tells browsers to refuse plain HTTP entirely for your domain, even if a user types http:// manually or clicks a stale link.

What HSTS actually does

HSTS is defined in RFC 6797. When a browser receives a valid Strict-Transport-Security response header over HTTPS, it stores that policy for the duration specified in max-age. For the lifetime of that policy, the browser will:

  • Automatically rewrite any http:// request for that host to https:// before sending it.
  • Refuse to let users click through certificate warnings — there is no "proceed anyway" button on an HSTS-protected host.
  • Optionally apply the same rules to every subdomain, if includeSubDomains is set.

Critically, the header is ignored when received over plain HTTP. This prevents an attacker from injecting or stripping the policy on the unencrypted hop. The first secure visit "primes" the browser; from then on, the policy is enforced locally.

The header format

A typical production HSTS header looks like this:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Three directives, each doing one job:

  • max-age — seconds the browser should remember the policy. 31536000 is one year, the minimum for preload eligibility.
  • includeSubDomains — extends the policy to every subdomain, including ones you haven't deployed yet.
  • preload — signals your intent to be added to the browser preload list (more on this below).

The trust-on-first-use problem and the preload list

HSTS has one inherent weakness: the very first visit to your site is unprotected, because the browser hasn't seen the header yet. An attacker who controls the network during that first request can still strip HTTPS.

The browser preload list solves this. It's a hardcoded list, maintained by Google and shipped with Chrome, Firefox, Safari, Edge, and others. Domains on the list are HTTPS-only from the very first request, with no prior visit required.

Requirements for preload submission

  1. Serve a valid certificate on the apex domain and all subdomains.
  2. Redirect HTTP to HTTPS on the same host (not directly to another domain).
  3. Serve all subdomains over HTTPS, including www.
  4. Send the HSTS header on the HTTPS apex with: max-age of at least 31536000, includeSubDomains, and preload.
  5. Submit at hstspreload.org.

Removal from the preload list takes weeks to months to propagate. Treat it as a one-way door.

Common ways HSTS gets misconfigured

Most HSTS problems aren't with the header itself — they're with how it interacts with the rest of your infrastructure.

Sending HSTS over HTTP

Browsers ignore HSTS on plain HTTP responses. If your server adds the header globally without checking the scheme, you're wasting bytes and giving a false sense of security. Only send it on HTTPS responses.

includeSubDomains breaking internal services

If you turn on includeSubDomains while internal.example.com or jenkins.example.com still listens on plain HTTP, those services will become unreachable from any browser that has seen the header. Audit every subdomain — including ones owned by other teams — before enabling this directive.

Short max-age in production

Some sites deploy max-age=300 and never raise it. That's fine as a rollout phase, but it offers almost no real protection. Once you're confident HTTPS is stable, ratchet up: 5 minutes → 1 day → 1 week → 1 month → 1 year.

Cached redirects defeating policy changes

If you push a misconfigured HSTS header with a one-year max-age and need to roll back, users who received it are stuck for a year unless they manually clear HSTS state in their browser. There is no remote kill switch.

A safe rollout sequence

  1. Confirm HTTPS works everywhere. Every subdomain, every asset path, every API endpoint. Mixed content warnings mean you're not ready.
  2. Enable a 301 redirect from HTTP to HTTPS on the same host.
  3. Ship the header with a short max-age. Start with max-age=600 (10 minutes), no includeSubDomains, no preload.
  4. Monitor for a week. Watch error rates, CDN logs, and any reports of broken integrations.
  5. Raise max-age incrementally over a few weeks until you reach 31536000.
  6. Add includeSubDomains only after auditing every subdomain in DNS.
  7. Add preload and submit once you're certain you'll never need to serve any part of the domain over HTTP again.

Verifying HSTS is actually working

The header has to arrive intact on an HTTPS response, with the correct directives, and only on HTTPS. A few quick checks:

  • curl: curl -sI https://example.com | grep -i strict should return your header.
  • Plain HTTP: curl -sI http://example.com should redirect with a 301 to HTTPS — and crucially, should not include the HSTS header on the HTTP response.
  • Browser devtools: open the Network tab, click the document request, and inspect the Response Headers.
  • Preload status: paste your domain into hstspreload.org to see eligibility and current list membership.

For a faster audit across multiple environments — staging, CDN edges, regional load balancers — run the URL through the AXOX Hub HTTP Header Checker. It surfaces every response header, follows redirects, and shows exactly what an end-user's browser sees, which makes it easy to spot when a reverse proxy is silently stripping or duplicating the Strict-Transport-Security directive.

HSTS alongside other security headers

HSTS protects the transport layer, but it doesn't replace the rest of your header stack. Pair it with:

  • Content-Security-Policy — controls which resources can load and execute.
  • X-Content-Type-Options: nosniff — prevents MIME-type confusion attacks.
  • Referrer-Policy — limits what referrer data leaks to third parties.
  • Permissions-Policy — restricts browser features like geolocation and camera access.

None of these overlap with HSTS in scope, and all of them are cheap to deploy once your HTTPS pipeline is solid.

Audit your domain's full header stack now with the free HTTP Header Checker at AXOX Hub — it'll show your current HSTS configuration, flag missing directives, and let you confirm the policy is enforced on every response.

Try the free tool

Open Tool