How to Implement HTTP Strict Transport Security
SEO guide explaining how to implement http strict transport security. Learn the best practices, setups, and automation tricks.
What HSTS does and why it matters
HTTP Strict Transport Security (HSTS) is a security policy defined in RFC 6797. A website sends it as a response header over HTTPS, and the browser remembers it. For the duration the site specifies, the browser will automatically rewrite any http:// link to https:// before sending a request, and it will refuse to let the user bypass certificate errors for that host.
Without HSTS, a visitor who types example.com into the address bar usually makes a first request over plain HTTP, then gets redirected to HTTPS. That first unencrypted request is a window for an attacker on the same network, such as a malicious Wi-Fi hotspot, to intercept the connection and keep the user on HTTP (a technique often called SSL stripping). HSTS closes that window for every visit after the browser has seen the header once, and the preload list closes it even for the very first visit.
Inspect Any Domain and Web Hosting Instantly
Inspect the infrastructure of any domain or website in seconds using TLDix WHOIS Domain, Hosting Lookup and Domain Oracle (AI).
HSTS is not a replacement for HTTPS itself. It is a layer on top of a correctly configured TLS setup that tells browsers to never fall back.
The header syntax explained
The header has one required directive and two optional ones:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
| Directive | Meaning | Notes |
|---|---|---|
max-age | How long, in seconds, the browser should enforce HTTPS for this host | Required. 31536000 is one year; 0 tells the browser to forget the policy |
includeSubDomains | Applies the policy to every subdomain of the host | Optional, but required for preloading |
preload | Signals consent to be added to browser preload lists | Not part of RFC 6797; used by the preload list maintainers |
A few rules are easy to miss:
- Browsers ignore the header when it arrives over plain HTTP. It only counts when delivered over a valid HTTPS connection.
- Each time the browser receives the header, the countdown restarts, so a regularly visited site effectively stays protected indefinitely.
- Only send one Strict-Transport-Security header. Duplicates, often caused by setting it both in the application and the web server, can lead to the policy being ignored.
Prerequisites before you turn it on
Because HSTS removes the option of falling back to HTTP, prepare carefully. Work through this checklist first:
- Valid certificates everywhere. Every hostname that will be covered must serve a trusted, unexpired certificate that matches the name.
- A working HTTP to HTTPS redirect. Requests on port 80 should return a 301 to the HTTPS version of the same URL.
- No mixed content. Scripts, images, fonts and API calls should load over HTTPS. HSTS upgrades links to your own host, but third-party resources on HTTP will still be blocked or flagged.
- A subdomain inventory. List every subdomain in your DNS zone, including old staging hosts, mail webmail portals, internal tools and vendor-hosted pages using CNAMEs. Any of them that cannot do HTTPS will break once you add includeSubDomains.
- Certificate renewal you trust. Automated renewal (for example via ACME) plus independent expiry monitoring.
For the inventory and monitoring steps, a renewal tracker helps: you can record each certificate and domain in TLDix domain tracking and receive alerts well before anything expires.
A safe, staged rollout
The biggest HSTS mistake is jumping straight to a one-year policy with includeSubDomains. If something breaks, visitors who already received the header stay locked to HTTPS until the max-age runs out, and you cannot recall it from their browsers. A staged approach limits the blast radius:
| Stage | Example header | Typical duration |
|---|---|---|
| 1. Test | max-age=300 | A day or two |
| 2. Short | max-age=86400 | About a week |
| 3. Subdomains | max-age=604800; includeSubDomains | A few weeks |
| 4. Long-term | max-age=31536000; includeSubDomains | Ongoing |
| 5. Preload (optional) | max-age=63072000; includeSubDomains; preload | Ongoing |
The durations are guidelines rather than rules. Move to the next stage only after checking logs and user reports for anything that stopped working.
Configuring HSTS on common servers
Nginx
Add the header inside the HTTPS server block. The always parameter makes Nginx send it on error responses too.
server {
listen 443 ssl;
server_name example.com www.example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# ssl_certificate and other directives here
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Remember that in Nginx an add_header inside a nested location block replaces headers inherited from the server level, so repeat it where needed or use an include file.
Apache
Enable mod_headers and add the directive to the SSL virtual host:
<VirtualHost *:443>
ServerName example.com
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
CDNs and application frameworks
Many CDNs and reverse proxies offer an HSTS toggle in their dashboard, and most web frameworks have middleware for it. Pick one place to set the header. If the CDN adds it and your origin does too, you may end up with duplicate or conflicting values.
The HSTS preload list
Major browsers ship with a built-in list of domains that are HTTPS-only from the very first request. Being on it removes the trust-on-first-use gap. The list is managed through the submission site at hstspreload.org, and its requirements (check the site for the current version) generally include:
- A valid certificate and a redirect from HTTP to HTTPS on the same host.
- All subdomains served over HTTPS.
- The header on the base domain with a long max-age (at least one year at the time of writing), includeSubDomains and preload.
Preloading is a long-term commitment. Removal is possible, but it reaches users only as browsers ship updates, which can take months. Some TLDs are preloaded as a whole, meaning every domain under them is HTTPS-only by default in supporting browsers. If you are choosing a new name, you can check options with the domain search tool and factor this in.
HSTS and related security headers
HSTS is often deployed alongside other response headers, and it helps to understand how they differ. Content-Security-Policy with the upgrade-insecure-requests directive tells browsers to fetch subresources on your pages over HTTPS, which complements HSTS when old content still contains HTTP links to third parties. HSTS, by contrast, governs how the browser connects to your host itself. Neither replaces the other, and setting both is common on mature sites. Review them together whenever you change your CDN or reverse proxy, because a configuration rebuild can drop several headers at once.
Testing and verifying your policy
Confirm the header from the command line:
curl -sI https://example.com | grep -i strict-transport-security
Then check behaviour, not just presence:
- Request
http://example.comand confirm it redirects to HTTPS with a 301. - In Chromium-based browsers, the internal
net-internals/#hstspage lets you query whether a domain has a stored policy and delete it during testing. - Test each subdomain over HTTPS before adding includeSubDomains, including rarely used ones.
- Re-test after deployments, CDN changes or server migrations, since headers are often lost when configuration is rebuilt.
Common pitfalls and how to avoid them
- Forgotten subdomains. An old intranet host or a vendor page on a CNAME that lacks a certificate will fail once includeSubDomains applies. Audit DNS first.
- Certificate expiry. With HSTS, browsers block access entirely when a certificate is invalid. A lapsed certificate turns from a warning into a full outage. Monitor expiry dates independently of your renewal automation.
- Setting the header on HTTP responses. It is ignored there, so it gives no protection and can confuse audits.
- Development domains. Avoid sending HSTS from local or test hosts that share a parent domain with production unless they also support HTTPS.
- Rolling back. To withdraw a policy, serve
max-age=0over HTTPS. Browsers that see it will forget the rule, but those that never revisit keep it until expiry.
HSTS works best as part of a broader hardening plan. Pair it with CAA records to control which authorities can issue certificates, and review the wider domain security best practices for the account and DNS side.
Keeping HSTS healthy over time
Once deployed, HSTS needs little attention as long as HTTPS stays healthy. Build a few habits into your operations: keep the subdomain inventory current, include the header check in deployment tests, and track every certificate and domain renewal date. You can look up where a site is hosted and confirm details with the hosting lookup when auditing older properties. The policy is only as reliable as the certificates and domain registrations underneath it, so treat renewals as part of the same security control.