Upgrade-Insecure-Requests: the request header vs the CSP directive (tested)

Two different things share this name: a request header Chrome sends, and a CSP directive your server sends. We logged every request to see what each one does.

1. The request header: Upgrade-Insecure-Requests: 1

Chrome sent Upgrade-Insecure-Requests: 1 on every page navigation (HTTP and HTTPS pages alike) and on none of the image, script or favicon requests. It means "this browser prefers HTTPS; you may redirect me". You don't set it, and seeing it in your logs is normal. A server may answer an HTTP request carrying it with a redirect to HTTPS (HSTS does this job better).

2. The CSP directive: what got upgraded

The page's HTML referenced http:// URLs; this is the scheme the request actually used:

PageCSPhttp:// imagehttp:// scriptMixed-content warnings
HTTPnoneHTTPHTTP-
HTTPupgrade-insecure-requestsHTTPSHTTPS-
HTTPSnoneHTTPS (Chrome auto-upgrades images)Blocked, never requestedYes, one per resource
HTTPSupgrade-insecure-requestsHTTPSHTTPS, ranNone
Content-Security-Policy: upgrade-insecure-requests

# nginx
add_header Content-Security-Policy "upgrade-insecure-requests" always;

# HTML (works as a meta tag too)
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

If you already send a CSP, add it as one more directive, e.g. default-src 'self'; upgrade-insecure-requests (CSP header examples). In Content-Security-Policy-Report-Only it did nothing; Chrome logs "The Content Security Policy directive 'upgrade-insecure-requests' is ignored when delivered in a report-only policy." The <meta> version worked like the header in our test. Build the full set in the free security headers generator.

Frequently asked questions

What does Upgrade-Insecure-Requests: 1 mean?

It is a request header the browser sends on page navigations to say it prefers HTTPS. In our Chrome test it was sent on navigations only, never on images or scripts.

Do I need to set the Upgrade-Insecure-Requests header?

No. The browser sends the request header. What you can set is the CSP directive upgrade-insecure-requests in a Content-Security-Policy response header or meta tag.

Does upgrade-insecure-requests fix mixed content?

Yes for resources whose host serves HTTPS: in our test an http:// script blocked as mixed content loaded over HTTPS and ran once the directive was added. Hosts without HTTPS fail instead (ERR_SSL_PROTOCOL_ERROR).

Does upgrade-insecure-requests change the port?

No, only the scheme; http://host:8996 became https://host:8996. Per the spec port 80 maps to 443.

Is upgrade-insecure-requests a replacement for HSTS?

No. It rewrites subresource URLs inside your pages; HSTS makes the browser use HTTPS for your whole domain.

Written with AI assistance. Measured on 2026-10-01 in Chromium 153 (full build), fresh context per row, non-loopback test hostnames (site.test / img.test mapped with --host-resolver-rules, self-signed certificate accepted): an HTTP page and an HTTPS page each loaded http:// images and scripts from a port that only speaks HTTPS and from a port that only speaks plain HTTP, with and without Content-Security-Policy: upgrade-insecure-requests (also as a <meta> tag and as Report-Only on the HTTPS page); the servers logged the scheme and request headers of every request. Link-navigation upgrades and the port-80→443 rule are from the spec, not this test. PlainHeaders is our extension; the other methods are free.