Strict-Transport-Security (HSTS) Header Missing: How to Fix It

No Comments
Strict-transport-security (hsts) header missing: how to fix it

TL;DR: The HSTS header forces browsers to use HTTPS for your domain on every request, closing the man-in-the-middle window that a plain redirect leaves open. It's not a ranking factor, but it locks users onto your canonical HTTPS URLs. Start with a short max-age, then ramp to a year.

What a missing HSTS header means

The Strict-Transport-Security (HSTS) header tells the browser to only ever connect to your domain over HTTPS — even if a user types http:// or clicks an old link — so if it's missing, that very first request still travels in the clear and can be hijacked before your redirect fires. This closes the tiny but real window that a plain HTTP-to-HTTPS redirect leaves open to a man-in-the-middle attacker.

Like most security headers, HSTS is not a direct ranking factor. Its SEO value is defensive: it locks users onto the canonical HTTPS version of every URL, which keeps your protocol signals clean and stops the kind of session-hijacking that leads to hacked-site warnings.

A real example and the fix

A site that redirects to HTTPS but never sends HSTS looks fine in a browser yet returns nothing here:

$ curl -sI -A 'Mozilla/5.0' https://example.com/ | grep -i strict-transport
# (no output — header absent)

The fix is one header. This is the exact value GitHub ships in production — a full year, all subdomains, preload-eligible:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Re-check after deploy and the header comes back:

$ curl -sI -A 'Mozilla/5.0' https://example.com/ | grep -i strict-transport
strict-transport-security: max-age=31536000; includeSubDomains; preload

What each HSTS directive does

TokenMeaningRecommendation
max-age=31536000How long (seconds) the browser remembers to force HTTPS1 year once you're confident
includeSubDomainsApplies the rule to every subdomain tooAdd only after confirming all subdomains do HTTPS
preloadOpts into the browser-baked preload listAdd last; submission is one-way and slow to reverse
max-age=0Tells the browser to forget the policyEmergency kill-switch only

Why HSTS closes a gap plain redirects can't

Say a user on cafe Wi-Fi types yourdomain.com. The browser fires http://yourdomain.com, your server answers with a 301 to HTTPS, and everything looks secure from there. But that first HTTP request — and the redirect response — travelled in the clear, and anyone on that network can intercept it and rewrite the redirect to a look-alike phishing host. HSTS shuts this down: once a browser has seen your header, it upgrades to HTTPS before sending anything, so that first plaintext request never happens again. The preload list goes one step further, baking the rule into the browser so even the very first visit is protected. This is the whole reason HSTS exists on top of a redirect — not redundancy, but covering the one moment the redirect can't.

How to detect it

  1. curl: curl -sI -A 'Mozilla/5.0' https://yourdomain.com/ | grep -i strict-transport-security. Silence means it's missing.
  2. securityheaders.com: the scan lists HSTS presence, the max-age value, and whether includeSubDomains and preload are set.
  3. hstspreload.org: Google's official checker tells you whether your header qualifies for the preload list and why not if it doesn't.
  4. Screaming Frog: the Security tab flags "Missing HSTS Header" across every crawled URL in one pass.

How to fix it

Send the header only over HTTPS — never on the plain-HTTP response, per the spec. Start with a short max-age, confirm nothing breaks, then ramp up.

Apache (.htaccess)

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
</IfModule>

Nginx

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Place this inside the server block that listens on 443, not the port-80 block.

WordPress (no server access)

Send it from PHP when you can't reach the server config:

add_action('send_headers', function () {
  if (is_ssl()) {
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
  }
});

The is_ssl() guard keeps the header off any plain-HTTP response, which the spec requires.

The safe ramp

Ship max-age=300 first (five minutes). Browse the whole site, check subdomains, watch for anything that still needs plain HTTP. Bump to max-age=86400, then to a year, then — and only then — add preload and submit to hstspreload.org. Set includeSubDomains; preload with a subdomain that isn't HTTPS-ready and you'll hard-block it in every browser, with a slow, painful path to undo it.

Common mistakes

  • Sending HSTS over HTTP. Browsers ignore the header on plain-HTTP responses by design — it only counts over HTTPS. Gate it behind an HTTPS check.
  • Jumping straight to a one-year max-age with preload. If one asset or subdomain still needs HTTP, you've locked users out with no quick undo.
  • Adding includeSubDomains before auditing subdomains. A legacy blog. or shop. subdomain on HTTP will break the moment the directive lands.
  • Forgetting the redirect. HSTS doesn't replace the 301 from HTTP to HTTPS — it complements it. Drop the redirect and first-time visitors have nothing to upgrade from.

FAQ

Is HSTS a Google ranking factor?

No. Google confirmed years ago that HTTPS is a lightweight signal, but HSTS specifically is not scored. You add it for security and clean protocol handling, not for a rankings bump.

Do I still need HTTP-to-HTTPS redirects if I have HSTS?

Yes. The redirect handles the very first visit before the browser has ever seen your HSTS header; HSTS protects every visit after that. Keep both — see HTTP does not redirect to HTTPS.

What's the difference between HSTS and CSP?

HSTS forces the connection to stay encrypted; Content-Security-Policy controls what content is allowed to load over it. Different jobs, and you want both.

Should I add preload right away?

No. Preload bakes your domain into browsers and is deliberately hard to reverse. Run a long max-age with includeSubDomains in production for weeks first, confirm every subdomain is HTTPS-only, then submit.

Will HSTS help my HTTPS migration?

It's the finishing move, not the opener. Complete the migration, verify canonicals and redirects, then lock it in with HSTS. Our HTTPS migration checklist covers the full sequence.

Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.

About SEO ProCheck

Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.

Work With Me

Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.

Subscribe to our newsletter!

More from our blog