What Is HSTS and How to Enable It
A practical guide to HTTP Strict Transport Security: how HSTS forces HTTPS, blocks SSL-stripping and downgrade attacks, its directives, and how to enable it.
HSTS is the header that turns "we support HTTPS" into "we only do HTTPS". In one line, HTTP Strict Transport Security (HSTS) is a response header that tells the browser to connect to your domain over HTTPS and nothing else, for a period you set. Once a browser has seen it, every future request to your site is upgraded to HTTPS before it leaves the device — closing the small but real gap that a plain redirect leaves open. This guide explains what HSTS protects against, the three directives that make it up, the browser preload list, and exactly how to enable and verify it without locking yourself out.
It builds directly on what is HTTPS and why your site needs it — HTTPS is the protocol, HSTS is what enforces it — and it is one of the headers covered in the broader HTTP security headers explained guide.
Answer first: what HSTS does
When a site sends the Strict-Transport-Security header, the browser records a rule: for this domain, use HTTPS only, and do so for the next N seconds. From that moment, if a user types http://yoursite.com, clicks an old http:// link, or follows a bookmark to the insecure version, the browser silently rewrites the request to https:// before sending anything over the network. And if, for any reason, a valid TLS connection cannot be established, the browser does not fall back to HTTP and does not let the user click through a warning — it simply refuses. That strictness is the whole point.
The problem: a redirect is not quite enough
Most sites already redirect HTTP to HTTPS with a 301, and that is correct and necessary. But there is a subtle weakness in a redirect alone. To learn that it should be on HTTPS, the browser first sends an http:// request, receives the redirect, and only then connects securely. That first request travels in the clear, and on a hostile network — public Wi-Fi, a compromised router, a malicious access point — an attacker positioned in the middle can intercept it.
This enables an SSL-stripping (or downgrade) attack: the attacker intercepts the initial HTTP request, prevents the upgrade to HTTPS, and proxies the connection so the victim continues talking to the attacker over plain HTTP while the attacker talks to the real site over HTTPS. The victim sees a working page, no padlock alarm bells in many cases, and never reaches the secure version. Everything they send — credentials, form data, session cookies — passes through the attacker in cleartext.
HSTS removes the opening. After the browser has recorded the policy, there is no first HTTP request to intercept — the upgrade happens locally, on the device, every single time. The attacker has nothing to strip.
The cookie angle
There is a second, often-overlooked reason HSTS matters: cookies. If a browser sends even one http:// request to your domain before a redirect, any cookie not marked Secure can be transmitted over that cleartext request and captured. A stolen session cookie can mean a hijacked account. By eliminating the insecure request entirely, HSTS protects cookies in transit at the protocol level — a useful complement to setting cookie attributes correctly, which we cover in how to secure cookies with HttpOnly, Secure, and SameSite. The two work together: HSTS keeps the whole connection on HTTPS, and the Secure flag ensures a cookie is never sent over HTTP regardless.
The three directives
The HSTS header is short, and its value is built from up to three directives:
max-age=<seconds>— required. How long the browser should remember to enforce HTTPS-only for this domain. Each valid HTTPS response refreshes (resets) the countdown, so an active site keeps the policy alive indefinitely. One year (31536000) is the common production value.includeSubDomains— optional. Applies the policy to every subdomain of the domain, not just the exact host that sent the header. Powerful, but it means all subdomains must be reachable over HTTPS, or they break for anyone who has seen the header.preload— optional. A signal that you consent to your domain being added to the browser-shipped preload list (see below). It has no effect on its own; it is a prerequisite for submitting to the list.
A typical production header looks like this:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
| Directive | Required? | What it does | Caution |
|---|---|---|---|
max-age | Yes | Seconds the browser enforces HTTPS-only | Long values are sticky — start short |
includeSubDomains | No | Extends the policy to all subdomains | Every subdomain must be on HTTPS |
preload | No | Opts into the browser preload list | Removal is slow; near-permanent |
The preload list
HSTS has one gap of its own: the very first time a browser ever visits your site, it has not yet seen the header, so that single initial visit is not protected by HSTS. For most sites this residual risk is small, but for high-value domains there is a way to close it: the HSTS preload list.
The preload list is a list of domains, maintained by the Chromium project and compiled into Chrome, Firefox, Safari, Edge and others, that browsers treat as HTTPS-only before any header is seen — even on a user's first-ever visit. To be eligible, per hstspreload.org, your site must:
- Serve a valid certificate.
- Redirect all HTTP to HTTPS on the same host.
- Serve the HSTS header on the base domain with
max-ageof at least one year (31536000). - Include both
includeSubDomainsandpreloadin the header.
You then submit the domain at hstspreload.org. The important caveat: getting onto the list is much faster than getting off it. Because the entry ships inside browser binaries, removal takes months to propagate to users. Only preload a domain when you are confident every current and future subdomain will be on HTTPS for the long term. For many sites, a long max-age with includeSubDomains is plenty, and preload is an optional final step.
How to enable HSTS safely
The single rule that prevents disasters: HSTS is sticky, so roll it out in stages. Once a browser caches a long max-age, it will refuse HTTP for your domain for that whole period, and users cannot override the resulting error. Get it wrong on a subdomain and you have a self-inflicted outage you cannot quickly undo. Here is the safe sequence:
- Get HTTPS working everywhere first. Every page, asset and subdomain must serve correctly over HTTPS with a valid certificate, and HTTP must already 301-redirect to HTTPS. If you are not there yet, fix that before touching HSTS. (See the HTTPS guide and, for the certificate side, what is an SSL certificate and how to check yours.)
- Start with a short
max-age. Begin with something likemax-age=300(five minutes) ormax-age=86400(one day), with noincludeSubDomainsand nopreload. If something is wrong, it expires almost immediately. - Verify, then increase. Confirm the header is present and the site works, then step the value up — a week, then a month.
- Add
includeSubDomainsonly after you have checked that every subdomain (including ones you rarely think about —mail.,dev.,legacy.) is on working HTTPS. - Raise
max-ageto one year (31536000) once you are fully confident. - Add
preloadand submit at hstspreload.org only if you want the extra first-visit protection and are committed to HTTPS-only across all subdomains indefinitely.
The header is set on the web server or CDN. The mechanism is the same everywhere — emit the Strict-Transport-Security response header on HTTPS responses — but the exact configuration directive differs by platform, so consult your server or CDN documentation for the precise syntax. Note: browsers ignore the HSTS header when it is sent over plain HTTP, by design; it only takes effect when delivered over HTTPS.
How to verify HSTS is working
Three quick checks confirm your header is live and correct:
1. curl -I from a terminal. Request the page and read the response headers:
curl -I https://example.com
Look for a line beginning strict-transport-security: and confirm the max-age and any directives are what you intended.
2. Browser DevTools. Open DevTools → Network, reload the page, click the main document request, and read the Response Headers for Strict-Transport-Security. For the wider technique of reading what a server returns, see how to read a website's HTTP headers.
3. Header graders. Tools such as securityheaders.com and Mozilla Observatory check for the presence and strength of HSTS as part of an overall grade and will flag a missing or weak header. To confirm eligibility for the preload list specifically, check the status page at hstspreload.org, which tells you exactly which requirement, if any, is unmet.
Broader site audits fold this in too — StackOptic reports HSTS and the rest of your security headers alongside performance and SEO, so you see the header in context rather than as an isolated check.
Common mistakes
- Enabling HSTS before HTTPS is solid everywhere, locking users out of any subdomain or page still on HTTP. The classic self-inflicted outage.
- Jumping straight to
max-age=31536000withincludeSubDomainson day one, with no short-value testing phase — leaving no quick way back if something is wrong. - Adding
includeSubDomainswithout auditing subdomains, breaking that forgottenlegacy.example.comfor everyone who has seen the header. - Preloading prematurely, then discovering a subdomain that cannot do HTTPS — and facing a slow removal from the browser-shipped list.
- Sending the header only over HTTP, where browsers ignore it; it must be served on HTTPS responses to take effect.
- Forgetting that
max-ageresets on every visit, so to truly disable HSTS you must servemax-age=0for long enough that all clients expire it — you cannot just remove the header and expect instant effect.
A quick HSTS checklist
- Confirm HTTPS works on every page and subdomain, with HTTP already 301-redirecting.
- Add
Strict-Transport-Securitywith a shortmax-agefirst. - Verify with
curl -Ior DevTools, then increasemax-agein steps. - Add
includeSubDomainsonly after auditing all subdomains. - Reach
max-age=31536000once confident. - Optionally add
preloadand submit at hstspreload.org, understanding removal is slow. - Re-check periodically with a header grader.
Go deeper
- The protocol it enforces: what is HTTPS and why your site needs it.
- All the protective headers: HTTP security headers explained.
- Protect cookies in transit too: how to secure cookies with HttpOnly, Secure, and SameSite.
- Read what a server sends: how to read a website's HTTP headers.
Want HSTS and your other security headers checked in one place? Analyse any URL with StackOptic — security, performance and SEO in one free report.
Frequently asked questions
What is HSTS?
HSTS (HTTP Strict Transport Security) is an HTTP response header that instructs a browser to only ever connect to a domain over HTTPS for a stated period. Once the browser has seen the header, it automatically upgrades any http:// request for that domain to https:// before sending it, and refuses to connect if a valid certificate is not present. It closes the small window where an initial insecure request could be intercepted and downgraded.
What problem does HSTS solve that a redirect does not?
A 301 redirect from HTTP to HTTPS still requires the browser to make one insecure request first, which an attacker on the network can intercept and strip back to HTTP before the redirect fires. HSTS removes that first insecure request entirely: after the browser has recorded the policy, it never sends an http:// request to your domain at all, so there is no cleartext moment for an attacker to exploit.
What does the max-age directive do in HSTS?
max-age sets how long, in seconds, the browser should remember to use HTTPS only for your domain. A common production value is 31536000 (one year). During a rollout you start with a short value, such as 300 (five minutes) or 86400 (one day), so any mistake expires quickly, then raise it once you are confident every page and subdomain works over HTTPS. Each valid response refreshes the timer.
What is the HSTS preload list?
The HSTS preload list is a list of domains, maintained by the Chromium project and shipped inside major browsers, that are treated as HTTPS-only even on a user's very first visit, before any header is seen. To qualify, your site must serve a valid certificate, redirect HTTP to HTTPS, set a max-age of at least 31536000, and include the includeSubDomains and preload directives, then submit at hstspreload.org. Removal is slow, so preload with care.
Can enabling HSTS break my site?
It can if applied carelessly. Because the browser caches the policy and refuses HTTP for the whole max-age, any subdomain or page that is not yet on working HTTPS becomes unreachable for users who have seen the header — and they cannot click through the warning. That is why you confirm HTTPS works everywhere first, start with a short max-age, and add includeSubDomains and preload only after verifying every subdomain. Rolled out in stages, HSTS is safe.
Analyse any website with StackOptic
Get the full technology stack, performance, security and SEO report in seconds — free.
Analyse a websiteRelated articles
How to Check a Website for Malware
A practical guide to checking any website for malware: the free external scanners to use, the signs of infection, server-side checks, and what to do next.
What Is a Data Breach and How to Respond
A plain-English guide to data breaches: what counts as one, the common causes, a step-by-step incident-response plan, the GDPR 72-hour rule, and prevention.
How to Protect Your Website from Bots and Scrapers
Not all bots are bad. Tell good crawlers from abusive scrapers, spot the signals of bot traffic, and layer rate limiting, CAPTCHA, a WAF and bot management.