Mixed Content Errors: Fixing HTTP Resources on an HTTPS Page
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an
insecure script 'http://cdn.example.com/app.js'. This request has been blocked; the content
must be served over HTTPS.
An HTTPS page that loads anything over plain HTTP is serving mixed content. The insecure request can be read or altered by anyone on the network path — and a tampered script can rewrite the whole page — so browsers refuse to load it.
What gets blocked
- Scripts, stylesheets, iframes, fonts,
fetch()and XHR, WebSockets (ws://) — always blocked. These can change the page or read its data. - Images, audio and video — current browsers first try them over HTTPS automatically and block them only if that fails. The page may look fine in your browser and still be broken for others.
Forms are covered too: Chrome warns before submitting a form from an HTTPS page to an http:// URL.
Find every insecure request
- DevTools → Console lists each blocked request with its URL.
- DevTools → Network: filter by
http:to see what's being requested insecurely. - View source and search for
http://— remember inline styles (url(http://…)),srcsetand JSON embedded in the page.
Fix it
Change the URLs to https://. Almost every CDN, font host and API serves HTTPS today. Use https:// explicitly rather than protocol-relative //cdn.example.com/… URLs, which are a leftover from when HTTPS was optional.
Use relative URLs for your own assets (/static/app.js) so they follow whatever protocol the page uses.
Fix stored content. In a CMS, old posts often contain http:// links to your own images. Run a search-and-replace on the database (WordPress has plugins and wp search-replace for this), and make sure the site URL setting itself uses https://.
Fix URLs your app generates. Behind a load balancer or CDN that talks to your app over HTTP, frameworks build absolute URLs with http:// because that's what they see. Trust the proxy's X-Forwarded-Proto header — app.set("trust proxy", 1) in Express — as covered in the redirect loop guide.
Drop resources that have no HTTPS version. If a third party only serves HTTP, host the file yourself or find an alternative.
Safety nets
Two headers help once the URLs are fixed:
Content-Security-Policy: upgrade-insecure-requests
Strict-Transport-Security: max-age=31536000; includeSubDomains
upgrade-insecure-requeststells the browser to rewrite everyhttp://subresource URL on the page tohttps://before requesting it. It's a quick fix for a legacy site with thousands of hard-coded URLs — but if a host has no HTTPS version, the request simply fails.- Strict-Transport-Security makes the browser use HTTPS for your own domain, even for
http://links to it.
The old block-all-mixed-content directive is deprecated; browsers block active mixed content by default now.
For the full set of headers worth sending, see the security headers checklist.