You added the Strict-Transport-Security header, but browsers still allow HTTP connections. Or HSTS works on the main domain but not on subdomains. This is common because HSTS has specific requirements and is easy to misconfigure. This guide explains why HSTS is not working and how to fix it.
What HSTS does
HSTS (HTTP Strict Transport Security) tells browsers to only connect to the site over HTTPS. Once a browser receives the HSTS header, it remembers it for the duration specified in max-age and refuses to connect over HTTP.
The header looks like this:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Key parts:
— max-age: how long the browser remembers HSTS;
— includeSubDomains: applies HSTS to all subdomains;
— preload: allows inclusion in browser preload lists.
If any part is missing or incorrect, HSTS may not work as expected.
Reason 1: header is not sent over HTTPS
HSTS headers are only honored when sent over HTTPS. If the header is sent over HTTP, browsers ignore it. This is a common mistake when the server sends the header on both HTTP and HTTPS, or only on HTTP.
What to check:
— is the header sent over HTTPS;
— is the header sent on HTTP by mistake;
— is the header sent on all HTTPS responses;
— is the header missing on some pages.
The fix: send the HSTS header only over HTTPS, on all HTTPS responses.
Reason 2: max-age is too short or zero
If max-age is too short, the browser forgets HSTS quickly. If max-age is zero, HSTS is effectively disabled.
What to check:
— is max-age set to a reasonable value;
— is max-age not zero;
— is max-age not too short (e.g., 60 seconds).
Recommended: start with a short max-age (e.g., 300 seconds) for testing, then increase to 31536000 (1 year) once everything works.
Reason 3: includeSubDomains missing
If includeSubDomains is missing, HSTS applies only to the exact domain, not to subdomains. If a subdomain is accessed over HTTP, the browser may allow it.
What to check:
— is includeSubDomains present;
— do all subdomains support HTTPS;
— are there subdomains that do not support HTTPS.
Be careful: if includeSubDomains is set and a subdomain does not support HTTPS, users will not be able to access it. Make sure all subdomains support HTTPS before enabling includeSubDomains.
Reason 4: HSTS not cached yet
HSTS only takes effect after the browser has received the header at least once. If you just added HSTS, users who have not visited the site since then will not have HSTS cached.
What to check:
— have users visited the site since HSTS was enabled;
— is the header sent on all HTTPS responses;
— is the browser using cached HSTS.
HSTS cannot be forced on users who have never visited the site. Preload lists help with this, but they require submission and approval.
Reason 5: preload requirements not met
If you want to use the preload list, you must meet specific requirements. If not, the site will not be included in the preload list, and HSTS will not apply to first-time visitors.
Preload requirements:
— valid HTTPS certificate;
— redirect from HTTP to HTTPS;
— HSTS header with max-age of at least 31536000;
— includeSubDomains;
— preload directive;
— all subdomains must support HTTPS.
If any requirement is not met, the site will not be included in the preload list.
For a full check, use HSTS checker to see whether the header is sent, what max-age is set, and whether includeSubDomains and preload are present.
How to diagnose HSTS issues
A practical sequence:
— check the HSTS header over HTTPS;
— check max-age;
— check includeSubDomains;
— check preload;
— check that the header is not sent over HTTP;
— check subdomains;
— check browser cache.
If the header is correct but HSTS does not work, the issue may be in browser cache or in the fact that the browser has not received the header yet. In that case, test with a fresh browser profile.
For a broader security audit, SEO audit can help verify HSTS, SSL, CSP and other security headers in one place.
How to fix HSTS
Fix steps:
— send the HSTS header only over HTTPS;
— set max-age to a reasonable value;
— add includeSubDomains if all subdomains support HTTPS;
— add preload if you meet all requirements;
— test with a fresh browser profile;
— monitor after changes.
FAQ
Why is HSTS not working?
Most often because the header is not sent over HTTPS, max-age is too short or zero, includeSubDomains is missing, or the browser has not received the header yet.
Can HSTS be sent over HTTP?
No. Browsers ignore HSTS headers sent over HTTP. The header must be sent over HTTPS.
What max-age should I use?
Start with a short value for testing, then increase to 31536000 (1 year) once everything works.
What is includeSubDomains?
It applies HSTS to all subdomains. Only enable it if all subdomains support HTTPS.
What is HSTS preload?
It adds your domain to a browser preload list, so HSTS applies even to first-time visitors. It requires meeting specific requirements.
Can HSTS break subdomains?
Yes. If includeSubDomains is set and a subdomain does not support HTTPS, users will not be able to access it.
How do I test HSTS?
Use a fresh browser profile, check the HSTS header, and verify that HTTP requests are redirected to HTTPS. An HSTS checker can help.
Does HSTS affect SEO?
Indirectly. HSTS improves security and user trust, which can positively affect SEO. It also prevents mixed content issues.
Can I disable HSTS?
You can stop sending the header, but browsers will remember HSTS until max-age expires. To disable HSTS for users, set max-age to zero and wait.
Why does HSTS work on the main domain but not on subdomains?
Because includeSubDomains is not set, or because subdomains do not support HTTPS. Check both.