Security headers only help if they land on every real response path, including error pages and redirects. I emit HSTS solely from the TLS server block (never from the cleartext listener), keep a long max-age once rollouts are stable, and pair it with a short preload candidate only after every subdomain is on 443. CSP is allowlist-first; I start report-only, fix the noisy sources, then flip enforce — otherwise a missing CDN or font host silently breaks production UI.
Ops check after reload: hit the apex, a static asset, and a 404 through nginx and confirm Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, and frame defenses appear without leaking Server/version noise. Watch for add_header inheritance traps — a location that sets its own headers can drop the parent set unless you repeat the critical ones. If a reverse-proxied app also sets CSP, pick one owner or you get duplicate policies that browsers treat inconsistently.