--- description: How to deploy HTTP Strict Transport Security safely, from a five minute test to preload, using the free Report URI HSTS tool. --- # HSTS ## What is HSTS? HTTP Strict Transport Security tells a browser that your site must only ever be reached over HTTPS. Once a browser has seen the header, it refuses to make a plaintext request to your site at all — it rewrites `http://` to `https://` before the request leaves the machine, and it will not let a visitor click through a certificate warning. That closes a gap that a redirect alone cannot. If someone types your domain into the address bar, their first request goes out over HTTP and can be tampered with before your redirect ever reaches them. HSTS removes that first request. The header is a single line: Strict-Transport-Security: max-age=31536000; includeSubDomains `max-age` is how long, in seconds, the browser should remember the instruction. `includeSubDomains` extends it to every subdomain of the host that sent it. ## The one thing to understand first **HSTS is not reversible on a schedule you control.** A browser that has seen `max-age=31536000` will refuse plaintext connections to your site for a year, and there is no way to reach out and correct that. If a subdomain turns out not to serve HTTPS properly, it is unreachable for those visitors until their `max-age` runs out. This is why the header is deployed as a ramp rather than switched on. Each stage is a commitment you can still walk back from, and each one lasts long enough to surface a problem before the next stage makes it expensive. !!! note "Roll back by lowering, not by removing" Removing the header does **not** undo it — browsers that already have the instruction keep honouring it. To back out, serve `max-age=0` and leave it in place until the longest value you previously published has expired. Deleting the header simply leaves the old instruction running. ## Getting Started Use our free [HSTS tool](https://report-uri.com/tools/hsts-checker) to check what your site sends today and to generate the right header for the stage you are at. It checks the things that have to be true before HSTS is safe — that HTTPS works, that the certificate is one a browser will accept, and that your HTTP requests redirect to HTTPS on the same host first — and recommends the next step rather than the final one. The stages below are the ramp. Do not skip them. ### 1. Five minutes Strict-Transport-Security: max-age=300 Long enough to prove the header is being served and that nothing immediately breaks. Short enough that a mistake has cleared itself by the time you have made a cup of tea. ### 2. One week Strict-Transport-Security: max-age=604800 Leave this running for a week. You are looking for anything that quietly depended on plaintext — an old link in an email footer, a monitoring check, a webhook from a partner. ### 3. One month Strict-Transport-Security: max-age=2592000 By now the cost of a mistake is a month of unreachability for affected visitors, so only move here once the previous stage ran clean. ### 4. One year Strict-Transport-Security: max-age=31536000; includeSubDomains A year is the value the preload list expects and the value most sites settle on permanently. You do not have to go further than this — a site running `max-age=31536000; includeSubDomains` has the protection HSTS offers. ##### PHP header("Strict-Transport-Security: max-age=31536000; includeSubDomains"); ##### Nginx add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; ##### Apache Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" ##### IIS Open IIS Manager and navigate to the level you want to manage. In Features View, double-click HTTP Response Headers. On the HTTP Response Headers page, in the Actions pane, click Add. In the Add Custom HTTP Response Header dialog box use the following name and value and then click OK. Name: `Strict-Transport-Security` Value: `max-age=31536000; includeSubDomains` ## includeSubDomains `includeSubDomains` applies the instruction to every name beneath the host that sent the header. On `example.com` that covers `www.example.com`, `mail.example.com`, `staging.example.com`, and anything else that exists now or is created later. That last part is what makes it worth care. It applies to subdomains you have forgotten about, subdomains another team runs, and subdomains that do not exist yet. An internal tool on a plain HTTP subdomain becomes unreachable, and you cannot fix it by removing the directive. So before switching it on, establish that **every** name under your domain serves HTTPS with a valid certificate. This is the one part of an HSTS rollout nobody can do for you: working out which subdomains exist means knowing your own DNS, and anything enumerated from the outside finds the hosts that already serve HTTPS while missing the ones that do not — which is the wrong way round, because those are the hosts the directive takes offline. The names that actually bite are the ones that are not websites: dev and staging hosts, admin panels, anything on an unusual port, wildcard DNS resolving names nobody remembers creating, subdomains pointed at a third party whose certificate is not yours to fix, and internal-only names that happen to resolve publicly. Our tool will ask you to confirm you have checked, and take your word for it — the ramp above is what validates the claim, which is why it starts at five minutes. When you turn `includeSubDomains` on, drop `max-age` back to 300 and walk the ramp again. The directive changes what the instruction covers, so the previous stages tell you nothing about the new scope. Our tool does this for you automatically rather than offering it as advice. ## Preloading Browsers ship a built-in list of sites that are HTTPS-only, so that even a visitor's very first request is protected. Being on it removes the last plaintext request entirely. To signal that you want to be included, add `preload` to the header: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload Then submit the domain at [hstspreload.org](https://hstspreload.org/). !!! warning "Preloading is effectively permanent" Removal is a manual request that takes months to reach users, and it only reaches them as they update their browser. Some never do. Treat submission as a decision about the domain's whole future, not a configuration change. Only submit once you have run a year of `max-age=31536000; includeSubDomains` without incident, and only for a domain you are certain will be HTTPS-only indefinitely. Preload applies to a registrable domain — `example.com`, not `www.example.com`. If you check a subdomain with our tool, it will validate the header and help you generate one, but it will tell you that the preload question belongs to the domain above it. #### Useful Links [https://scotthelme.co.uk/hsts-the-missing-link-in-tls/](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) [https://scotthelme.co.uk/hsts-preloading/](https://scotthelme.co.uk/hsts-preloading/) [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) [https://hstspreload.org/](https://hstspreload.org/) ## Check your header with Report URI **Already using us?** Run the [HSTS tool](https://report-uri.com/tools/hsts-checker) against your domain — it reads what you are serving today and tells you the next safe step rather than the final one. **New to Report URI?** The [HSTS tool](https://report-uri.com/tools/hsts-checker) is free, needs no account, and does not ask who you are. An account is for the reporting that comes after: [Certificate Transparency](/setup/certificate-transparency/) monitoring tells you when a certificate is issued for your domain, and CSP reporting tells you what is actually running on your pages. [Start your free trial](https://report-uri.com/register/?plan=starter2025)