Section 7.2 of RFC 6797 states:

An HSTS Host MUST NOT include the STS header field in HTTP responses
conveyed over non-secure transport.

In practice, I have a lot of hosts that are behind an Amazon load balancer that where requests from ports 443 and 80 are forwarded to the same Nginx configuration. It would be considerably simpler to always send the Strict-Transport-Security header, regardless of the incoming protocol used.

I don't care if the UA ignores the header on insecure requests. I'd just to like to confirm if this RFC violation causes a problem in practice.

Insecure requests are already redirected to secure versions by the server, where the UA would then receive a valid Secure-Transport-Security header in their response.

  • Clarification: You want to send the header back on all requests? Dec 18, 2015 at 22:45
  • 1
    I have never seen or heard of anywhere it causes a problem in practice, to this point. I know there was at least one very large site that has, at least in the past, intentionally sent HTST headers on HTTP requests, seemingly without issue. As chexum points on in his answer, because of the MUST NOT, this will not necessarily always be the case.
    – Xander
    Dec 18, 2015 at 23:10
  • 3
    (After migration) Dupe of security.stackexchange.com/questions/84714/… which answers that 8.1 says client MUST ignore HSTS on HTTP. Also security.stackexchange.com/questions/103507/… Dec 19, 2015 at 0:37

2 Answers 2


If the requirement is MUST NOT, then in theory some browser can display an error instead of a page that has this header when fetched via plain HTTP. It is highly unlikely though.

(Update: this unlikely behaviour is actually forbidden by the same RFC.)

Clearly the point is that over HTTP nothing can be trusted to originate from the original server, so if any browser would interpret it when seen with HTTP, then this header could be (ab)used to force the server appear offline for an extended time without the consent of the server operator, with sufficient capabilities to control the network path.

New UA/client software authors still could make a mistake of interpreting this header, and it can be a good protection against this if you make it a requirement to not ever issue HSTS via HTTP - so that it can be flagged and reported as an error by any validator.

Though I did not test this, with nginx, it's not very complicated to say:

if ($scheme = https) {
    add_header Strict-Transport-Security max-age=18000000;

The only issue I can foresee is when you have a limited SSL offloading frontend proxy and you can't easily tell whether the request is SSL or not. In that case you actually must issue HSTS via HTTP, assuming your CDN/proxy does not have a way to configure HSTS.


While the if directive can be used to limit the HSTS header to HTTPS, it becomes messy when you have multiple location blocks in your virtual host file. I came across the following solution in an Nginx trac ticket.

map $scheme $hsts_header {
    https   max-age=31536000;

server {
    listen  80;
    listen  443 ssl;

    add_header Strict-Transport-Security $hsts_header;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .