A secure page that pulls one asset over plain HTTP is mixed content, and browsers deal with it by upgrading or refusing it. Either way the page you shipped is not the page that renders. Reporting tells you exactly which resources are involved, so you can fix the source rather than the symptom.
Mixed content stopped being a warning triangle a long time ago. Browsers now refuse insecure scripts and frames outright, and upgrade or block insecure images without asking. That means the practical consequence is rarely a security banner — it is a feature that does not work, on someone else's device, with no error anywhere you are looking. A page can carry mixed content for years while everyone who builds it sees it working perfectly.
An insecure script that the browser refuses to run does not throw an error your monitoring will catch. The functionality it provided simply is not there, and the only people who experience that are the visitors it was meant to serve.
Mixed content accumulates in old blog posts, seldom-visited templates, email-rendered pages and content typed into a CMS years ago. Crawling for it means crawling everything, including what sits behind a login.
Every new integration, every pasted embed code and every content author with an image URL is another chance for it to come back. Without ongoing detection, a completed migration slowly stops being complete.
A Content Security Policy can report mixed content from real page loads and, if you want, have the browser upgrade it while you work through the list. One is the diagnosis, the other is the plaster.
Reports come from your visitors' browsers, which means the inventory covers the pages a crawler cannot reach — authenticated areas, personalised content, region-specific templates, and the archive nobody has opened in three years. Each report names the resource and the page it was referenced from.
Learn more about CSP Reporting →The upgrade-insecure-requests directive tells the browser to request insecure subresources over HTTPS instead. It resolves the visible symptom immediately, which buys time — but it is a redirect layer over a list of references that are still wrong, and it will not help where the resource genuinely has no HTTPS version. The reports are how you know which is which.
Because reporting runs continuously rather than as a one-off scan, a new insecure reference introduced by a content author, a new embed or a vendor change shows up as soon as a visitor loads the page. A migration you finished stays finished, which is not the usual outcome.
Learn more about Script Watch →One header. No code. Reports start arriving from your first visitor.
30-day free trial · One header · No code · Cancel anytime
The treatment depends on what the resource is capable of doing to the page. Knowing the categories explains why some mixed content breaks a feature and some merely disappears.
| Resource | How it is treated |
|---|---|
| Scripts and stylesheets | Active content — refused outright, so the functionality is gone |
| Frames | Active content — refused, leaving an empty region on the page |
| fetch and XMLHttpRequest | Active content — the request fails and whatever depended on it fails too |
| Images, audio and video | Passive content — upgraded where possible, otherwise blocked |
| upgrade-insecure-requests | Asks the browser to request insecure subresources over HTTPS |
| Report-only policy | Reports what is insecure without changing any behaviour |
Upgrading only works where the resource is genuinely available over HTTPS. Where it isn't, the reference has to be replaced — which is why the inventory matters more than the directive.
Detection happens in the browser, on real page loads, which is what makes it complete. A crawler finds mixed content on the pages it can reach; your visitors find it everywhere, including behind authentication and in content that only renders for certain users.
Start in report-only and nothing changes. One header builds the list without altering how any page behaves.
Content-Security-Policy-Report-Only: upgrade-insecure-requests;
report-uri https://your-subdomain.report-uri.com/r/d/csp/reportOnly
When you want the browser to start upgrading as well as reporting, move the directive into your enforcing Content-Security-Policy header. The reporting continues either way.
Mixed content reporting is among the easiest ways to start with Content Security Policy, because the directive is short, the findings are unambiguous, and there is no allowlist to research first. It produces a concrete list of things to fix on day one.
If you want to go further afterwards, the CSP Wizard will build a full policy from your own reports and the CSP Builder will let you maintain it.
This covers resources referenced insecurely. It does not tell you whether a securely-loaded resource is trustworthy — it is the transport-consistency layer, and it works alongside the rest.
| Covers | Using |
|---|---|
| Finding insecure references | CSP for reporting and for upgrading |
| What those resources actually are | Script Watch for dependency inventory and change detection |
| Whether the policy itself stays in place | Policy Watch for detecting header changes |
| Certificate problems visitors encounter | Network Error Logging for TLS failures in the field |
Together, these form the browser-native security layer that sits between your application and the code executing around it.