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 tohttps://example.combefore 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:
| Value | Duration | Use Case |
|---|---|---|
| `300` | 5 minutes | Initial testing |
| `86400` | 1 day | Short-term evaluation |
| `2592000` | 30 days | Gradual rollout |
| `31536000` | 1 year | Production standard |
| `63072000` | 2 years | Required 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.comtomorrow - 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-ageof 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.