HSTS checker
Check whether the Strict-Transport-Security header is configured for forced HTTPS connections
Check results
This check only covers HSTS. For a full picture of your page, run a page audit.
For issues across your whole site — duplicate titles, orphan pages, broken internal links — run a site audit.
Want us to fix what we found? Our team can help.
What is HSTS and why it matters
HSTS (HTTP Strict Transport Security, RFC 6797) is a response header that tells the browser "for this host, never use plain HTTP — always HTTPS, even if the user types http:// explicitly, even if a link points at HTTP." After the first HTTPS response with a Strict-Transport-Security header, the browser remembers the policy for the duration of max-age and rewrites every subsequent HTTP request to HTTPS internally, before any network traffic. This closes the SSL-strip attack window that exists with a regular HTTP→HTTPS redirect, where the first unencrypted request can be intercepted and rewritten by an attacker on the network path.
What this tool checks
- Applicability — if the site runs on HTTP, HSTS is not meaningful (RFC 6797 §7.2 requires browsers to ignore HSTS over HTTP); the SSL checker handles the missing-HTTPS case separately
- Header presence — whether the HTTPS response includes
Strict-Transport-Security - Directive parsing — case-insensitive parse of
max-age,includeSubDomains, andpreload(per RFC 6797 §6.1) - max-age validity — flags very small values (under 1 day) as likely stale warm-up values left over from rollout
- Preload compatibility — if
preloadis set, verifies thatmax-age≥ 31536000 (1 year) and thatincludeSubDomainsis also set, as both are required by hstspreload.org
How the three directives interact
- max-age — how long (in seconds) the browser should remember the HSTS policy. Recommended production value: 31536000 (1 year). Longer is safer; shorter values should only appear during warm-up
- includeSubDomains — applies the HSTS policy to every subdomain (
api.example.com,mail.example.com,staging.example.com). Required for preload submission. Enable only after verifying every subdomain serves HTTPS - preload — the magic token that makes your domain eligible for the HSTS Preload List, a hardcoded table built into Chrome, Firefox, Safari, and Edge. Domains in the preload list are HSTS-protected from the very first visit, even if the user has never been to the site before. Submit at hstspreload.org
Good vs bad examples
Good — production-ready HSTS with preload:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Good — HTTPS-enforcing HSTS without preload (apex only, no subdomain commitment):
Strict-Transport-Security: max-age=31536000
Good — warm-up value during initial HSTS rollout (1 week):
Strict-Transport-Security: max-age=604800; includeSubDomains
Bad — very small max-age left over after warm-up was supposed to ramp up:
Strict-Transport-Security: max-age=300
Bad — preload requested but max-age too low to qualify:
Strict-Transport-Security: max-age=86400; includeSubDomains; preload
→ hstspreload.org will reject (requires ≥ 31536000)
Bad — preload requested without includeSubDomains:
Strict-Transport-Security: max-age=31536000; preload
→ hstspreload.org will reject (requires includeSubDomains)
Common mistakes
- Enabling preload without meaning to — copy-pasting
max-age=31536000; includeSubDomains; preloadfrom a tutorial, then discovering a subdomain that only works over HTTP. Preload is effectively one-way — see the FAQ below - Forgetting subdomains —
includeSubDomainscovers every subdomain, including the ones you forgot (mail, legacy admin panels, third-party integrations on custom subdomains). Enable only after a full subdomain audit - Stale warm-up max-age — deploying
max-age=300"just to test," then never ramping up. 5 minutes of HSTS protection is effectively no protection; the attack window is almost always open - HSTS on HTTP only — browsers ignore HSTS when received over HTTP (RFC 6797 §7.2); the header must come from an HTTPS response
- Missing
alwaysin Nginx —add_header Strict-Transport-Securitywithoutalwaysonly sends the header on 2xx/3xx responses, not on error pages. Users hitting a 500 still see plain HTTP. Always useadd_header Strict-Transport-Security "..." always; - Confusing HSTS with HTTP→HTTPS redirect — the redirect protects returning users on subsequent visits; HSTS protects returning users from the very first connection of each visit (no unencrypted request ever leaves the browser)
Frequently asked questions
preload when you're 100% certain you'll serve HTTPS on the apex and every subdomain indefinitely. If there's any uncertainty — a legacy system you might inherit, a subdomain managed by another team, a planned rebranding — don't enable preload yet.Strict-Transport-Security: max-age=0 over HTTPS. Browsers interpret max-age=0 as "forget this domain's HSTS policy immediately." Users who visit the HTTPS version of the site after you deploy max-age=0 will clear their stored HSTS state and can once again access the HTTP version. The catch: users who don't visit the HTTPS version again before your old max-age expires on their end will stay locked into HTTPS. If you removed HTTPS entirely, they'd have no way to receive the max-age=0 header. And if your domain was on the preload list — see the previous answer — max-age=0 does nothing, since the preload entry is browser-hardcoded.http:// request to https:// internally, before any packet leaves the browser. You should use both: 301 redirect for first-time visitors who haven't received the HSTS header yet, plus HSTS to protect returning visitors.