Detects HTTP resources on HTTPS pages and CSP upgrade directive
3 of 3 free audits left today
See what Mixed Content finds on your site. No sign-up needed.
Render β launches a headless Chromium as 37AuditsBot and navigates to the audited URL, waiting up to 60 s for the load event and then up to 15 s more for the network to go idle (a page that keeps polling is judged on the requests seen by then). A blocked page ends the audit with 590; no response or an HTTP status of 400 or more ends it with 500; a browser failure that survives one relaunch ends it with 501.
Collect β records every request the browser made while loading, plus the resolved src / href of every img, script, link, iframe, video, audio and source element left in the rendered DOM. A resource counts only when its URL starts with http:// (any letter case); the audited document and its redirect hops never count. Each URL is reported once, with the place it was first seen (request or dom).
Upgrade directive β reads Content-Security-Policy from the final response the browser rendered (after redirects); when there is no header, from a <meta http-equiv="Content-Security-Policy"> tag. The page has the safety net when one of the directives is upgrade-insecure-requests.
Rules β every insecure resource fails (400) when the directive is absent, or warns (300) when it is present. FAIL wins over WARNING; when nothing was loaded over plain HTTP the audit is SUCCESS (200) and names the number of requests observed.
Specification pin β every run emits 37A-MixedContentAuditor-100 (INFORMATION), naming the W3C Mixed Content (Level 2) Candidate Recommendation Draft of 2023-02-23. It does not change the overall status.
| Key | Type | Default | Description |
|---|---|---|---|
evaluateExternalResources | boolean | true | When false, resources served from a host other than the audited site or one of its subdomains (www. ignored) are not reported, even when they load over HTTP. Each one left out is listed as an INFORMATION check, 37A-MixedContentAuditor-101. Set it per monitored URL on the Configuration tab. |
An invalid value (anything but a boolean or "true"/"false") makes the auditor fall back to the default and log a warning.
Every row maps to one checkRule* method and one CheckCode, in the order the auditor runs them. CheckCode suffixes use status ranges: 100 information, 200 success, 300β399 warning, 400β499 fail, 500β599 error.
| CheckCode | Status | When it fires | Recommendation | Why it matters |
|---|---|---|---|---|
37A-MixedContentAuditor-100 | INFORMATION | Always. Records the specification version this auditor implements. | β (recommendation is null; nothing for the site to change) | β |
37A-MixedContentAuditor-400 | FAIL | One check per resource loaded over plain HTTP while the page sends no upgrade-insecure-requests directive. The check's resource is that URL. | Serve '{resource}' over HTTPS: change its URL to https:// or host a copy on a secure origin. As a stopgap, add 'upgrade-insecure-requests' to the Content-Security-Policy of {url}. | Browsers block insecure scripts, styles and frames on an HTTPS page and drop the padlock when images or media load over HTTP, so parts of the page break or look untrustworthy, and anyone on the network can tamper with what is loaded. |
37A-MixedContentAuditor-300 | WARNING | One check per resource referenced over plain HTTP while the page's Content-Security-Policy (header or meta) carries upgrade-insecure-requests. The check's resource is that URL. | Change the URL of '{resource}' to https:// in the page source so it no longer depends on the upgrade-insecure-requests directive. | The directive is a safety net, not a fix: older browsers and tools that ignore it still load the resource over plain HTTP, and the upgrade silently fails when the host has no HTTPS version, so part of your visitors see a broken or "Not secure" page. |
37A-MixedContentAuditor-200 | SUCCESS | All rules passed: no resource was loaded over plain HTTP. Message names the number of requests the browser made and whether upgrade-insecure-requests is sent. | β | β |
37A-MixedContentAuditor-500 | ERROR | The browser got no response for the page, or an HTTP status of 400 or more that is not a block. | Make sure {url} answers with HTTP 2xx, then run the audit again. Last error: {error}. | β |
37A-MixedContentAuditor-501 | ERROR | Playwright could not render the page (navigation timeout, browser crash on both launches, protocol error). | Make sure {url} loads in a headless Chromium browser, then run the audit again. Last error: {error}. | β |
37A-MixedContentAuditor-590 | ERROR | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See https://www.37audits.com/bot. | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |
37A-MixedContentAuditor-101 | INFORMATION | evaluateExternalResources is false: one check per external resource the page requested or referenced that was not checked, served from a host other than the audited site or one of its subdomains. The check's resource is that URL; data carries host, siteHost and evaluateExternalResources: false. Message: Not evaluated: the resource {resource} is served from {host}, outside {siteHost}, and Evaluate external resources is off. Never changes the result's status. | Turn on Evaluate external resources for this monitored URL to assess third-party resources too. | β |
| Status | Description | Test logic |
|---|---|---|
| SUCCESS | The page loaded nothing over plain HTTP | No request and no src / href in the rendered DOM starts with http://, the audited document excluded (200). |
| WARNING | Insecure references exist, but browsers upgrade them | One or more insecure resources and upgrade-insecure-requests in the CSP header or meta (300, one check per resource). |
| FAIL | Insecure resources are loaded as-is | One or more insecure resources and no upgrade-insecure-requests directive (400, one check per resource). |
| ERROR | The auditor could not load or render the page | No response or HTTP β₯ 400 (500); Playwright failure after the relaunch (501); site blocked 37AuditsBot (590). |
| INFORMATION | Specification pin | Always emitted (100); does not change overall status. |
Each 300 / 400 check carries resource, source (request when the browser fetched it, dom when only the rendered markup references it), hasUpgradeInsecureRequests and csp (the policy, truncated to 300 characters) in its data; the 200 check carries url, requestCount, hasUpgradeInsecureRequests and csp.
Browsers block insecure scripts, stylesheets, frames and fetches on an HTTPS page, so a single http:// script tag can take down a feature for every visitor.
Images, video and audio over HTTP are upgraded by current browsers and blocked when the upgrade fails; older browsers load them and drop the padlock, which visitors read as "this site is not safe".
A plain HTTP request can be read and rewritten on the network, so an insecure script is a remote code execution vector on your page.
upgrade-insecure-requests is a stopgapThe directive tells browsers to rewrite http:// requests to https:// before sending them. It hides the problem from visitors on current browsers, but the page source still points at insecure URLs, and the upgrade fails silently when the host serves no HTTPS. Fix the URLs and keep the directive as a safety net.
The auditor reads the directive from the response header first and from a <meta http-equiv> tag only when there is no header, like browsers combine them.
http:// inside a query string (for example ?u=http://example.com) no longer counts: a resource is flagged only when its own URL starts with http://.
The audited document and its redirect hops are never flagged, even when the audited URL is itself plain HTTP.
The Content-Security-Policy header is read from the final response after redirects; before, it was only found when no redirect happened.
A page that answers HTTP 400 or more is an ERROR (500) instead of being audited as if it were the site.
A browser failure is an ERROR with its own code (501) instead of the raw Playwright message with no code.
Verdict severities are unchanged: an insecure resource still fails, and still warns when upgrade-insecure-requests is present.
Only the audited URL is rendered; other pages of the site may load insecure resources.
Requests made after the 15 s network-idle cap, or after a user interaction, are not seen; the result message says so when the page never went idle.
A link element is reported whatever its rel, so an http:// canonical or alternate link shows up although browsers never fetch it.
Resources behind a consent banner or a login are only seen when the page loads them anyway.
This documentation is built and hosted on Mintlify, a developer documentation platform.
Add this auditor to your monitoring setup and start identifying issues on your websites today.