upgrade-insecure-requests — What It Does and When to Use It
Updated April 2026
Reading this? Verify your fix live. Scan your CSP → CSPFixer
upgrade-insecure-requests is a CSP directive that automatically upgrades HTTP resource requests to HTTPS before the browser makes them. It is a fast fix for mixed content warnings — but only works if the resources actually exist on HTTPS.
How it works
# Without upgrade-insecure-requests: # <img src="http://cdn.example.com/image.jpg"> # Browser requests: http://cdn.example.com/image.jpg # → Mixed content warning # With upgrade-insecure-requests: # Browser upgrades to: https://cdn.example.com/image.jpg before making the request # → No mixed content warning (if https resource exists)
Add to your CSP
# As a standalone directive (no value needed) Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; # With other directives Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; script-src 'self'; img-src 'self' https:;
Config by stack
Nginx
add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'self';" always;
Vercel (vercel.json)
{ "headers": [{ "source": "/(.*)", "headers": [{ "key": "Content-Security-Policy", "value": "upgrade-insecure-requests; default-src 'self';" }] }]
}
What it upgrades — and what it does not
| Resource type | Upgraded? | Notes |
|---|---|---|
| Images (<img src="http://...">) | ✅ Yes | Passive mixed content — upgraded |
| Scripts (<script src="http://...">) | ✅ Yes | Active mixed content — upgraded |
| Stylesheets | ✅ Yes | Upgraded |
| The page URL itself | ❌ No | Use HSTS for this |
| Form action URLs | ✅ Yes | Upgraded |
| XHR/fetch URLs in JavaScript | ❌ No | Must fix in code |
upgrade-insecure-requests vs block-all-mixed-content
# upgrade-insecure-requests → attempts HTTPS, fails gracefully if not available Content-Security-Policy: upgrade-insecure-requests; # block-all-mixed-content → blocks HTTP resources entirely, no upgrade attempt Content-Security-Policy: block-all-mixed-content; # Use upgrade-insecure-requests first — less disruptive # Only switch to block-all-mixed-content once all resources are on HTTPS
The complete mixed content fix
# Three layers working together: # 1. upgrade-insecure-requests — upgrades HTTP resource requests Content-Security-Policy: upgrade-insecure-requests; # 2. HSTS — forces HTTPS for the page itself Strict-Transport-Security: max-age=31536000; includeSubDomains # 3. Fix hardcoded HTTP URLs in your code — the real fix # Find with: grep -r "http://" ./src --include="*.js" --include="*.html"Scan your CSP → CSPFixer