Security & Authentication

HSTS: HTTP Strict Transport Security Complete Guide

How HSTS forces HTTPS connections, preload list submission, and handling HSTS deployment mistakes that can lock users out.

What Is HSTS?

HTTP Strict Transport Security (HSTS) is an HTTP response header that tells browsers to only connect to your site over HTTPS — and to refuse plain HTTP connections entirely.

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

Once a browser sees this header, it stores the HSTS policy and enforces HTTPS for the specified duration (max-age in seconds). During that time:

  • If the user types http://example.com, the browser internally rewrites it to https://example.com before making any network request
  • If the HTTPS connection fails (expired certificate, wrong hostname), the browser shows a hard error with no "proceed anyway" option
  • Any HTTP redirect from the server is converted to a local 307 Internal Redirect

Why It Matters

Before HSTS, even HTTPS-only sites were vulnerable to SSL stripping attacks (Moxie Marlinspike, BlackHat 2009). An attacker in a coffee shop could intercept the initial HTTP request (before the redirect to HTTPS) and proxy the connection over plain HTTP while showing the user a padlock icon via deceptive techniques.

HSTS eliminates the unencrypted first request — the browser never makes an HTTP connection to a site with an active HSTS policy.

The Strict-Transport-Security Header

max-age

The duration in seconds that the HSTS policy is remembered:

ValueDurationUse Case
`300`5 minutesInitial testing
`86400`1 dayShort-term evaluation
`2592000`30 daysGradual rollout
`31536000`1 yearProduction standard
`63072000`2 yearsRequired for preload list

Start with a short max-age during testing. Increase it only when you're confident your HTTPS setup is solid.

includeSubDomains

The includeSubDomains directive extends the policy to all subdomains:

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

With this, api.example.com, mail.example.com, and every other subdomain are also forced to HTTPS — even if they've never been visited before.

Important: Before adding includeSubDomains, verify that every subdomain of your domain serves HTTPS. Including it on a domain with HTTP-only subdomains will make those subdomains unreachable.

preload

The preload directive signals your intent to join the HSTS Preload List (hstspreload.org). This is a list of domains hardcoded into browsers. Browsers enforce HTTPS for these domains even on the very first visit — before ever seeing the HSTS header.

How Browsers Enforce HSTS

When a browser visits an HSTS-protected site:

  • Server responds with Strict-Transport-Security: max-age=31536000
  • Browser stores: example.com → HSTS until 2027-02-01, includeSubDomains: false
  • User types http://example.com tomorrow
  • Browser internally redirects to https://example.com (307 Internal Redirect — no network request is made to the HTTP URL)
  • If the HTTPS connection fails → hard error, no bypass option

The internal redirect is critical: the unencrypted request never leaves the device, eliminating the window for SSL stripping.

Certificate Errors Become Hard Failures

Without HSTS, a certificate error shows a warning with a "Proceed anyway" link. With HSTS active, that option disappears. The browser refuses to connect.

This is a security feature — it prevents attackers from using self-signed certificates in man-in-the-middle positions. But it means you must never let your TLS certificate expire on an HSTS-protected domain.

HSTS Preload List

Submission Requirements

To join the preload list, your domain must:

  • Serve a valid HTTPS certificate
  • Redirect all HTTP to HTTPS
  • Serve the HSTS header from the HTTPS base domain (not just www)
  • Use max-age of at least 31,536,000 seconds (1 year)
  • Include includeSubDomains
  • Include preload

The full header required:

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

Submit at https://hstspreload.org. The list is shared across Chrome, Firefox, Safari, Edge, and Internet Explorer 11+.

Processing Time

After submission, expect:

  • 1-3 months to appear in Chrome's build
  • 2-6 months to reach all browsers via updates

Removal Process

Removal from the preload list is possible but slow — 6-12 months. During that time, all browsers that received the preloaded list will still enforce HTTPS. This is why the preload list is a long-term commitment.

Deployment Strategy

Follow this graduated approach:

Week 1: Test with short max-age

Strict-Transport-Security: max-age=300

Verify that HTTPS works correctly. Check all subdomains.

Week 2-4: Extend max-age

Strict-Transport-Security: max-age=86400

Monitor for any HTTPS failures in error tracking.

Month 2: Add includeSubDomains

Strict-Transport-Security: max-age=2592000; includeSubDomains

Confirm all subdomains serve HTTPS first.

Month 3+: Production max-age

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

Optional: Preload

Only once you're committed to HTTPS permanently:

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

Recovery from Mistakes

Clearing HSTS Cache in Chrome

If you need to test HTTP access to your domain from Chrome:

  • Visit chrome://net-internals/#hsts
  • In the Delete domain security policies section, enter your domain
  • Click Delete
  • Verify: in the Query HSTS/PKP domain section, enter your domain — it should show "Not found"

Setting max-age=0 to Remove HSTS

To instruct browsers to forget your HSTS policy:

Strict-Transport-Security: max-age=0

Serve this header over HTTPS. The browser deletes its stored HSTS record for your domain. This is the correct way to undo HSTS if you're planning to run your site over HTTP again (though you should avoid ever going back to HTTP).

You Cannot Recover from Preload Mistakes Quickly

If your site is on the preload list and you lose HTTPS capability (expired certificate, server misconfiguration), users with the preloaded version cannot reach your site at all. There is no bypass.

The only recovery path is:

  • Restore HTTPS as fast as possible
  • Submit a preload removal request (takes months to propagate)

This is why the deployment strategy above emphasizes starting without preload and only adding it after months of stable HTTPS operation.

Certificate Expiry Monitoring

Set up automated alerts when your TLS certificate is within 30 days of expiry. For Let's Encrypt, configure certbot or acme.sh to auto-renew at 60 days. Test your renewal pipeline — a failed renewal that you don't notice until certificates expire is a production outage on HSTS-protected sites.

Related Protocols

Related Glossary Terms

More in Security & Authentication