What is HSTS and should you enable it?
// published 2026-04-17
HSTS — HTTP Strict Transport Security — is a single response header that tells browsers "from now on, only talk to my domain over HTTPS, and don't let the user click through certificate warnings." It's one of the highest-leverage security headers you can deploy, and it's one of the easiest to misconfigure in ways that bite hard.
What HSTS protects against
Two attacks:
- SSL stripping. User types
yourdomain.com(no protocol). Browser defaults to HTTP. Attacker on the same network intercepts the initial HTTP request and serves a downgraded, unencrypted version of your site. HSTS prevents this by forcing the initial request to HTTPS even when the user typed no protocol. - User-ignored certificate warnings. If your cert is misissued/expired, a normal browser shows a warning the user can usually bypass. With HSTS, the browser refuses to proceed — no "Advanced → Accept risk" button.
Check whether you have HSTS configured with the Security Headers Checker.
The header format
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age— how long (in seconds) the browser should enforce HTTPS-only. Production value is typically 31536000 (1 year) or higher.includeSubDomains— apply to every subdomain under this host. Powerful but irreversible without waiting out max-age.preload— signals that you want the domain baked into Chrome/Firefox/Safari's preload list. See below.
Deploy it safely
HSTS is self-inflicted damage if you turn it on wrong. The staged rollout:
Stage 1 — test with short max-age
Strict-Transport-Security: max-age=300
5 minutes. Enough to verify the header is being served from every origin you run; short enough to recover if you discover a subdomain that doesn't have HTTPS yet.
Stage 2 — bump to a real value
Strict-Transport-Security: max-age=31536000
1 year. If anything is going to break, it'll surface within the first day. Leave it running for a week before going further.
Stage 3 — add includeSubDomains
Only do this after you've audited every subdomain. That internal admin dashboard at admin.yourdomain.com? If it's HTTP-only, adding includeSubDomains will lock your staff out. Same for every legacy redirector, marketing microsite, or third-party service hosted on a subdomain.
Stage 4 — preload
Submit to hstspreload.org. Once accepted, your domain gets compiled into the HSTS preload list in every major browser. This is a one-way door — removing from the preload list takes months. Only do this after you've run with includeSubDomains and 1-year max-age in production for at least a few weeks.
When HSTS bites back
- You need to disable HTTPS for a subdomain temporarily. You can't. Browsers cached the HSTS directive; short of visiting each user's machine, you're waiting for max-age to expire.
- Your certificate auto-renewal breaks. Without HSTS, users see a warning and can click through. With HSTS, the site is unreachable — no workaround. Hence the importance of proactive SSL monitoring.
- A subdomain host doesn't support HTTPS. After
includeSubDomainsis deployed, all subdomains must have valid certs. Missed one? It's broken for every HSTS-aware browser.
One-line deployment examples
nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Rails (config/application.rb):
config.ssl_options = { hsts: { expires: 1.year, subdomains: true } }
After deploying, re-run the Security Headers Checker to confirm the header is being served and graded as "strong".