page-security-audit

nginx add_header in a location dropped my security headers

Grabzies Ecommerce · 23 September 2026 · 3 replies
I added a location block for .js and .css files with add_header Cache-Control "no-cache". Caching works as expected now, but a security scan says my scripts are missing Content-Security-Policy, HSTS and X-Content-Type-Options, which are all set at the server level.

Why did adding one header remove the others?
3 Replies
John Carlsson · 23 Sept 2026
That's nginx's inheritance rule: a location block inherits the server-level add_header directives only if it has no add_header of its own. As soon as you add one, all the outer ones are dropped for that block. It's one of the most common nginx surprises.

Two fixes: repeat all your security headers inside that location block, or avoid add_header there. For no-cache specifically, use:

expires epoch;

which sends Cache-Control: no-cache without being an add_header, so your security headers are still inherited.
Grabzies Ecommerce · 23 Sept 2026
Switched to expires epoch and the security headers are back on the JS files. Anything else to watch?
John Carlsson · 23 Sept 2026
Check the order of your regex locations. nginx uses the first regex location that matches, so a specific \.(css|js)$ block has to come before a general static-files block that also matches .js. Then confirm with curl -sI on a script: you want cache-control: no-cache, an etag and your CSP header all present. Our Security Audit checks the headers from outside too.

Join the discussion

Sign in to reply, share your SEO experience and connect with other members.