In ASP.NET Core, call UseHsts only outside Development and then UseHttpsRedirection. Redirection sends HTTP requests to HTTPS with a 307 by default. HSTS tells browsers to use HTTPS for future visits and defaults to a 30 day max age. Start with a short HSTS lifetime and raise it once HTTPS is stable.
Definitions
HTTPS redirection middleware turns an insecure request into a redirect to the HTTPS address. HSTS, HTTP Strict Transport Security, is an opt in response header. Once a browser has seen it, the browser forces all communication to that host over HTTPS and refuses to proceed past untrusted or invalid certificates. The first visit is still unprotected, which is why the background post on HSTS and the first visit gap matters.
What the Microsoft page documents
- UseHttpsRedirection uses the default redirect status code of 307 Temporary Redirect, and the HTTPS port comes from options, the ASPNETCORE_HTTPS_PORT variable or the server address feature. The docs recommend temporary redirects over permanent ones, because link caching can cause unstable behaviour in development.
- If no HTTPS port can be determined, redirection does not happen and the middleware logs the warning "Failed to determine the https port for redirect". This is a frequent surprise behind a proxy that terminates TLS.
- HSTS max age defaults to 30 days if not set. UseHsts excludes localhost, 127.0.0.1 and the IPv6 loopback by default.
- UseHsts is not recommended in development because browsers cache HSTS settings heavily.
- When first rolling out HTTPS, set a small max age, from hours to no more than a day, in case you must revert. Then raise it, commonly to one year.
Setup
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseHttpsRedirection();
builder.Services.AddHsts(o =>
{
o.MaxAge = TimeSpan.FromDays(365);
o.IncludeSubDomains = false;
});
Be careful with IncludeSubDomains and with preload. They affect every host under the domain, including old internal tools that may not support HTTPS.
APIs and redirects
For a pure API, redirecting a POST from HTTP to HTTPS is risky because the body may already have crossed the network in clear text. Many teams stop listening on plain HTTP for APIs and return an error instead, or terminate HTTP only at an edge that redirects. Client libraries that follow redirects can also drop or keep authorization headers in surprising ways, so do not rely on redirects to protect credentials. The right fix is that clients call HTTPS from the start.
Behind a proxy
When TLS ends at a load balancer, the app sees plain HTTP. Configure forwarded headers handling so the app knows the original scheme, and set the HTTPS port explicitly so redirection can work. Otherwise you get either redirect loops or the missing port warning. The proxy side is covered in TLS termination at the proxy.
Steps
- Serve the API only over HTTPS where you can.
- Add UseHsts outside Development with a one day max age first.
- Add UseHttpsRedirection and confirm the HTTPS port is detected.
- Test behind your real proxy, not only locally.
- Raise max age gradually, to one year once stable.
- Check subdomains before enabling IncludeSubDomains.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a live scan checks the response headers and transport settings of a web app.
Quick check
Why did HSTS not appear on localhost?
By default UseHsts excludes loopback addresses, and it is meant to run outside Development.
Can I undo HSTS quickly?
Only by waiting for the max age to expire in each browser, which is why starting small is the documented advice.
Safeguard dependency scanning and SBOM generation cover the NuGet packages in an ASP.NET Core service, and the free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.