How long should HSTS max-age be?
hsts-max-age-shortglobal
HSTS max-age should be 31536000 seconds minimum for production sites and 63072000 seconds for sites eligible for preload. The max-age directive specifies how many seconds browsers enforce HTTPS-only connections. Short max-age values under one year create frequent windows where HSTS expires and downgrade attacks become possible. Two-year max-age satisfies preload requirements and extends protection duration with minimal additional risk.
What’s wrong
The Strict-Transport-Security max-age value is below 31536000 seconds or missing entirely. Max-age values of 86400 (one day), 2592000 (30 days), or other short durations provide temporary protection that expires quickly. Each expiration creates a window where browsers revert to allowing HTTP connections. Short max-age forces the HSTS header to be re-sent frequently to maintain protection. Browsers that do not revisit before expiry lose HSTS enforcement.
Why it matters
HSTS protection disappears after max-age expires. Browsers that have not seen a renewed HSTS header within the max-age window begin attempting HTTP connections again. Attackers can exploit expired HSTS to perform downgrade attacks during this window. Short max-age values increase the frequency of these vulnerability windows. Users who visit infrequently may always hit expired HSTS. The protection becomes unreliable when max-age is too short. Long max-age values ensure consistent protection across user visit patterns.
The correct change
Set max-age to 31536000 seconds minimum for production sites. This one-year duration provides reliable protection across typical user visit frequencies. Use max-age=63072000 (two years) for sites submitting to the HSTS preload list. Two years is the preload requirement and balances long-term security with eventual expiry. Verify HTTPS works reliably before deploying long max-age values. Start with shorter values like 300 seconds during initial testing, then increase to production values after validation. The end state is max-age=31536000 or greater on all HTTPS responses.
Scope
This condition applies globally to the hostname. The max-age directive affects all paths on the hostname. Each HTTPS response that includes the Strict-Transport-Security header resets the expiration timer. Browsers maintain per-hostname HSTS state with the expiration calculated from most recent header. The setting affects only the specific hostname unless includeSubDomains extends coverage.
How to verify
- Validation confirms the condition is resolved:
- • Strict-Transport-Security header includes max-age=31536000 or greater
- • Browser internal HSTS list shows expiration date at least one year forward
- • Header appears consistently on all HTTPS responses
- • No HTTP connections succeed to the hostname from HSTS-aware browsers
- • Security scanners confirm HSTS max-age meets minimum requirements
- • Certificate expiry date extends beyond max-age period
Takeaway
- Production HSTS max-age should be at least 31536000 seconds (one year)
- Preload-eligible sites need max-age of 63072000 seconds (two years)
- Short max-age creates frequent expiration windows vulnerable to attack
- Each HTTPS response with HSTS header resets the expiration timer
- Test HTTPS thoroughly before deploying long max-age values
FAQ
Why not set max-age to maximum possible value?
Extremely long max-age values provide minimal additional security over one or two years. The risk of permanent lockout increases with duration. If HTTPS becomes unsupportable, extremely long max-age requires waiting years for expiry or difficult manual browser clearing. Two years balances strong protection with eventual recovery possibility. Practical considerations favor two years as the upper recommended value.
What happens to users who visit once then return after max-age expires?
Those browsers lose HSTS enforcement after expiry. The next visit allows HTTP connections until a new HSTS header is received over HTTPS. If the user requests HTTP directly, the connection succeeds without upgrade. If HTTP redirects to HTTPS normally, the new HSTS header re-enables enforcement. Long max-age reduces the likelihood of this scenario affecting users with long gaps between visits.
Should max-age increase gradually or jump to final value?
Start with short max-age during initial rollout for quick recovery if issues arise. Use 300 seconds for initial testing. Increase to 86400 after successful validation. Ramp to 2592000 after longer observation. Jump to 31536000 or 63072000 when confidence is high. Gradual increase allows backing out quickly during early stages while moving toward strong protection.
Does max-age affect HTTPS certificate renewal timing?
Certificates must remain valid for the entire max-age period after issuance. If a certificate expires before max-age, browsers with HSTS enforcement cannot connect. Users see certificate errors they cannot bypass. Coordinate certificate renewal to complete well before expiration. Automated renewal systems like Let’s Encrypt prevent this issue by renewing months before expiry.
Can different pages on the same hostname use different max-age?
Browsers use the most recently seen max-age value for the entire hostname. HSTS does not operate at path level. A response with max-age=63072000 on /login and max-age=31536000 on /about results in whichever value the browser saw most recently applying globally. Consistency across all responses prevents confusion. Configure one max-age value for all paths.
How does max-age interact with preload?
Preload has its own persistence independent of max-age. Domains on the preload list enforce HSTS until removed from browser code updates. Max-age still applies to determine when browsers expire locally learned HSTS for updates or removal. Preload requires minimum max-age=63072000 to qualify for submission. Both mechanisms reinforce each other for maximum protection.
The fix
Extend HSTS protection duration to eliminate frequent expiration windows
Done when: Strict-Transport-Security max-age set to 31536000 or 63072000 seconds on all HTTPS responses
Do not
- Do not use max-age values below 31536000 seconds for production sites
- Do not deploy long max-age values before thoroughly testing HTTPS functionality
- Do not vary max-age across different paths on the same hostname
- Do not set max-age longer than certificate validity period allows
How to verify
- HSTS header contains max-age=31536000 or greater
- Browser HSTS state shows expiration at least one year forward
- Header appears consistently across all HTTPS responses
- Security scanners confirm max-age meets production requirements
- Certificate validity extends beyond max-age period
Find every page with this
probeo monitors this continuously across every page of your site, and records which pages passed, which failed, and which it could not determine.
Book a Call