TLS protects an HTTP connection after the browser has chosen HTTPS and completed certificate validation. A separate problem exists before that protected connection begins: a user can type a bare hostname, follow an old HTTP link, or reach a page that redirects from HTTP to HTTPS.
HTTP Strict Transport Security, usually called HSTS, lets a site tell supporting browsers to treat future connections to that host as HTTPS-only. The browser stores the policy for a defined period. While the policy is active, an HTTP navigation is upgraded locally before an insecure HTTP request is sent.
That makes HSTS a useful transport policy, but deployment needs care. A long policy can remain in browsers after a configuration mistake is fixed on the server. The includeSubDomains directive extends the requirement to every descendant host. Preloading can remove the first-contact gap, but it also raises the operational commitment.
This article builds a practical model for deploying HSTS safely.
Start with the transport gap
Consider a site whose canonical address is:
https://portal.example.test/The server may also listen on port 80 only to return a redirect:
HTTP/1.1 301 Moved Permanently
Location: https://portal.example.test/That redirect is useful for ordinary navigation, but the first request still uses HTTP. An attacker able to interfere with that network path can tamper with the unprotected response. TLS certificate validation has not started yet.
With an active HSTS policy for the host, the browser changes the navigation internally:
http://portal.example.test/
|
v
https://portal.example.test/No HTTP redirect is needed for that browser. If the HTTPS connection presents an invalid certificate, the browser treats the failure as a hard error rather than offering the ordinary path around some certificate warnings.
HSTS therefore complements TLS. It does not replace certificate validation, secure TLS configuration, or correct redirects.
Send the policy only over HTTPS
A typical response header is:
Strict-Transport-Security: max-age=86400max-age is measured in seconds. It tells the browser how long the host should remain under the policy after receiving the header over a secure connection.
Do not depend on an HSTS header delivered over HTTP. An attacker on the insecure path could remove or alter it. Browsers process HSTS policy from secure HTTPS responses.
A small initial value is useful during rollout. One day gives operators time to detect certificate, routing, or hostname problems before committing clients to a long period.
After the HTTPS service has been stable, increase the duration deliberately:
Strict-Transport-Security: max-age=31536000A year is a common long-lived policy period. The correct duration still depends on the site’s ability to keep HTTPS valid throughout that interval.
Treat subdomains as a separate commitment
This directive expands the policy:
Strict-Transport-Security: max-age=31536000; includeSubDomainsIf a browser receives it from example.test, the HTTPS-only rule also applies to hosts such as:
api.example.test
status.example.test
old-app.example.test
team.internal.example.testThat is powerful because an overlooked HTTP-only subdomain cannot remain an easy downgrade path under the parent policy. It can also cause an outage if any required descendant host lacks working HTTPS.
Before adding includeSubDomains, inventory the namespace. Check production applications, static hosts, vendor integrations, forgotten administrative names, temporary environments, and hosts reached by automated browser flows.
A useful deployment invariant is:
Every required descendant host can complete valid HTTPS
before the parent asserts includeSubDomains.Do not use the directive as a way to force incomplete migration. Finish the migration first, then encode the resulting state as browser policy.
Understand the first-contact limitation
A browser cannot apply a policy it has never received. On a device with no stored HSTS state, the first visit can still begin over HTTP.
This creates a bootstrap gap:
first contact -> HTTP may still occur
later contact -> stored HSTS can force HTTPSHSTS preloading addresses that gap for eligible public sites. Browser vendors can ship a list of domains that should be treated as HSTS hosts before any network contact occurs.
Preloading is stronger than sending a response header alone, but it should be considered a long-term operational decision. Removal from browser preload data is not instant, and clients update on their own schedules.
Do not submit a domain for preloading until HTTPS is durable across the required namespace and the organization is prepared to maintain that state.
Roll out in stages
A safe rollout is progressive.
First, confirm that the target host serves HTTPS correctly. Test certificate chains, hostname coverage, redirects, application callbacks, downloads, WebSocket endpoints, and third-party integrations that use the host.
Next, send a short policy on the exact host:
Strict-Transport-Security: max-age=300Five minutes limits the impact of a mistake. Observe real traffic and synthetic checks.
Then increase the duration in steps:
5 minutes
1 day
1 week
1 month
1 yearThe exact ladder can differ. The important property is that each increase follows evidence that the previous stage is healthy.
Add includeSubDomains only after descendant hosts pass the same HTTPS readiness checks. Consider preloading last.
This sequence turns HSTS from a single risky switch into a controlled migration.
Keep HTTP redirects anyway
Once HSTS is active, it can be tempting to remove the HTTP listener. Keeping a minimal redirect service is often useful.
Not every client is a browser with stored HSTS state. New browsers may not have the policy yet. Some non-browser HTTP clients do not implement HSTS at all. A clean HTTP-to-HTTPS redirect also preserves expected behavior for ordinary links during migration.
The redirect is not the security boundary for HSTS-aware clients. It is compatibility behavior for traffic that still arrives over HTTP.
Keep the HTTP endpoint simple. It should redirect to a fixed trusted HTTPS origin rather than constructing security-sensitive destinations from untrusted request metadata.
Do not confuse HSTS with application controls
HSTS has a narrow job: require HTTPS for covered browser connections. It does not provide authorization, authentication, CSRF protection, output encoding, or content restrictions.
It also does not make an unsafe application safe merely because traffic is encrypted. An authenticated user can still be exposed to insecure object access, injection, or broken account recovery over a perfectly valid TLS connection.
A useful mental model is:
HSTS protects the choice of transport.
TLS protects the connection.
Application controls protect actions and data.Each layer handles a different boundary.
Plan certificate operations before long durations
A long HSTS duration makes certificate reliability more important. If a certificate expires or the deployed chain becomes invalid, affected browser users cannot fall back to HTTP.
That is a security benefit, but it changes the operational cost of certificate failure.
Before adopting a long policy, make certificate renewal routine and observable. Track expiry well ahead of the renewal window. Test automated renewal and deployment. Monitor the certificate actually served from each edge location rather than only checking a certificate stored in a control plane.
Also plan for emergency replacement. Operators should know how to deploy a new certificate, update load balancers or gateways, and confirm the result from outside the production network.
HSTS works best when certificate management is already dependable.
Test the effective policy
Checking source configuration is not enough. Verify the response seen by a real client:
curl -I https://portal.example.test/Look for a single valid header:
Strict-Transport-Security: max-age=31536000; includeSubDomainsTest representative routes because proxies, CDNs, application servers, and error handlers can produce different response paths. A policy present on the home page but absent from other HTTPS responses may still be refreshed often enough in practice, but consistent edge configuration is easier to reason about and audit.
Also test certificate failure behavior in a controlled environment. Confirm that the browser does not silently continue through an invalid secure connection for a host with active HSTS state.
For staged deployment, record the intended max-age, whether subdomains are covered, and whether preload status is part of the target state. That gives reviewers a concrete policy to compare with production.
Recover carefully from a policy mistake
A site can ask browsers to clear a dynamic HSTS policy by serving this over valid HTTPS:
Strict-Transport-Security: max-age=0That mechanism has an important constraint: users must still reach a valid HTTPS response to receive the change. If HTTPS is already broken, clearing the policy from the same broken host may not be possible for affected users.
A parent policy with includeSubDomains can also keep a descendant covered even if that descendant attempts to clear its own state.
Preloaded policy has a separate removal process and persists until updated browser data reaches clients.
These properties make prevention more valuable than emergency rollback. Short initial durations and staged expansion are operational security controls, not mere deployment convenience.
A compact deployment checklist
Before a long-lived HSTS policy, confirm all of these conditions:
- HTTPS works for every required covered host.
- Certificates renew and deploy reliably.
- HTTP endpoints redirect to fixed trusted HTTPS destinations.
- A short
max-agehas run without transport failures. - Subdomain coverage has an explicit inventory.
- Monitoring checks the externally served certificate and header.
- Emergency certificate replacement has a documented path.
- Preloading, if selected, is treated as a durable commitment.
The central idea is simple: HSTS converts a working HTTPS deployment into a browser-enforced transport rule. Deploy the transport first, verify it under real conditions, then increase the strength and duration of the rule in measured stages.