You spent hours setting up an SSL certificate, redirecting HTTP to HTTPS, and double-checking your nginx config. Then a user takes a screenshot: the padlock is gone, replaced by a "Not Secure" warning. Welcome to mixed content — one of the most common and most underestimated security issues on the web.
Mixed content happens when an HTTPS page loads sub-resources (images, scripts, iframes, fonts) over plain HTTP. Browsers treat this as a serious problem: passive mixed content downgrades the security indicator, and active mixed content (scripts, stylesheets, iframes) is blocked outright by every modern browser. The result is broken pages, missing widgets, and lost trust — even though your certificate is technically valid.
This guide walks you through what mixed content actually is, why browsers handle it the way they do, and how to find every offending resource on your site. We'll cover Chrome DevTools, automated scanners, code-level fixes for HTML, CSS, and JavaScript, and a Content Security Policy strategy that prevents the problem from ever coming back.
Check your site right now: Free ZeriFlow scan in 60 seconds →
What Is Mixed Content, Exactly?
Mixed content is any HTTP resource referenced from an HTTPS page. The page itself is encrypted, but at least one asset travels over an unencrypted channel. That single insecure request is enough to compromise the integrity of the entire page.
Browsers split mixed content into two categories:
Passive (or display) mixed content includes images, audio, and video. These resources can't directly execute code, so browsers usually allow them but strip the secure padlock and display a warning. An attacker who intercepts a passive request can swap one image for another or track the user, but they can't hijack the session.
Active mixed content includes scripts, stylesheets, iframes, XHR/fetch calls, and Web Workers. These can execute arbitrary code in the page's context. A man-in-the-middle could replace your analytics.js with a credential stealer. Because the risk is severe, browsers block active mixed content by default — the request never even leaves the device.
The practical consequence: a single <script src="http://..."> tag will simply fail to load on HTTPS, breaking whatever feature it powers. A single <img src="http://..."> will load but kill your padlock.
Why Mixed Content Breaks the Padlock (and Your Trust Signals)
The padlock icon is shorthand for "this connection is encrypted, authenticated, and tamper-proof." Mixed content invalidates two of those three guarantees. The HTTP request can be observed by anyone on the network path, and an active attacker can modify the response in transit. The browser has no way to verify that the image, script, or iframe you receive is the one your server intended to send.
Beyond the technical risk, mixed content has real business costs:
- SEO penalty. Google has flagged mixed content in Lighthouse audits since 2018 and uses HTTPS as a ranking signal. Pages with broken security indicators get downgraded.
- Conversion loss. Studies consistently show that visitors abandon checkout when the padlock disappears. A 2024 Baymard Institute study put cart abandonment from trust signals at 18%.
- Compliance issues. PCI-DSS, HIPAA, and most enterprise procurement checklists require end-to-end HTTPS. Mixed content can fail an audit.
- Feature breakage. Modern browser APIs (geolocation, service workers, push notifications, WebRTC, clipboard) are gated behind a "secure context" — and a page with mixed content may not qualify.
How to Detect Mixed Content on Your Site
There are four reliable ways to find mixed content. Use all of them — each catches things the others miss.
1. Chrome DevTools Console
Open DevTools (F12), go to the Console tab, and reload the page. Mixed content shows up as warnings or errors:
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS,
but requested an insecure resource 'http://cdn.example.com/banner.jpg'.
This content should also be served over HTTPS.The Security panel gives a higher-level view: it lists every origin loaded by the page and flags any that used HTTP. The Network panel, with the "Mixed content" filter, shows the actual requests. This is the fastest way to debug a single page, but it only checks the page you're currently viewing.
2. Automated Site-Wide Scanners
DevTools won't crawl your entire site. For that you need an automated scanner that fetches every page, parses the HTML, and reports every HTTP reference. ZeriFlow does this as part of its 80+ checks — point it at your domain and you get a complete inventory of mixed content issues across headers, HTML attributes, inline styles, and CSS imports, in 60 seconds.
3. Content Security Policy Reports
Deploy a CSP with block-all-mixed-content and a report-uri directive. Browsers will then send a JSON report every time a user hits a mixed content issue in production:
Content-Security-Policy: upgrade-insecure-requests; report-uri /csp-reportThis catches issues that only appear on specific user paths or third-party widgets that you don't see in your own testing.
4. Server Log Analysis
Grep your access logs for HTTP requests that have an HTTPS Referer header. Anything matching is, by definition, mixed content:
awk '$11 ~ /^"https/ && $7 !~ /^https/' access.logHow to Fix Mixed Content Errors
The fix is conceptually simple: serve every resource over HTTPS. In practice, you'll hit four common patterns.
Pattern 1: Hardcoded HTTP URLs in HTML
This is the easy case. Find and replace http://yourdomain.com with https://yourdomain.com (or with a protocol-relative path) across your templates, CMS, and database. For WordPress, the Better Search Replace plugin handles serialised data correctly. For static sites, a sed pass usually does the job:
grep -r "http://yourdomain.com" ./src
sed -i 's|http://yourdomain.com|https://yourdomain.com|g' ./src/**/*.htmlPattern 2: User-Generated Content in the Database
Old blog posts, forum threads, and product descriptions often contain <img src="http://..."> tags. You have two options:
- 1Run a migration that rewrites every URL in your content table.
- 2Rewrite at render time with a middleware that replaces
http://withhttps://for known-safe domains before the HTML hits the browser.
Option 1 is cleaner, option 2 is safer if you have third-party hosts whose HTTPS support you can't guarantee.
Pattern 3: Third-Party Widgets and CDNs
Some embeds (older ad networks, ancient analytics scripts, niche payment widgets) only ship HTTP URLs. The fix:
- Check the vendor's documentation for an HTTPS endpoint — most have supported it for years.
- If the vendor still doesn't, replace the widget. In 2026 there's no excuse for an HTTP-only third party.
- As a last resort, proxy the resource through your own HTTPS-enabled domain, taking ownership of the security implications.
Pattern 4: The Nuclear Option — upgrade-insecure-requests
Add this single header and the browser will rewrite every HTTP sub-resource request to HTTPS automatically:
Content-Security-Policy: upgrade-insecure-requestsThis is the fastest way to neutralise mixed content while you fix the underlying URLs. The catch: if a target server doesn't actually support HTTPS, the request will fail. Use it as a safety net, not a substitute for cleaning your codebase.
For a full breakdown of which security headers matter and how they interact, see our HTTP security headers guide.
Preventing Mixed Content in the Future
Once you've cleaned up, lock things down so it doesn't happen again:
- 1Enforce HTTPS at the load balancer with a 301 redirect from HTTP to HTTPS, plus HSTS with
includeSubDomainsand a longmax-age. - 2Add `block-all-mixed-content` to your CSP so passive mixed content fails loudly during development instead of silently in production.
- 3Add a CI check that greps your build output for
http://references in any HTML, CSS, or JS file. Fail the build if any are found. - 4Document an HTTPS-only policy for third-party scripts and CDNs in your engineering wiki.
- 5Re-scan regularly. Run a ZeriFlow scan on every deploy or at least weekly — mixed content has a way of sneaking back in through marketing pixels and CMS edits.
FAQ
Q: What's the difference between mixed content and an invalid SSL certificate?
A: An invalid certificate means the page itself can't be trusted — wrong domain, expired, self-signed, untrusted CA. Mixed content means the page is fine but it pulls some resources over HTTP. Browsers treat them differently: invalid certs trigger a full-page interstitial; mixed content drops the padlock or blocks specific assets.
Q: Will upgrade-insecure-requests fix mixed content permanently?
A: It hides the symptom by rewriting HTTP to HTTPS at request time, but only works if the destination supports HTTPS. It won't fix typos, dead resources, or HTTP-only services. Treat it as a safety net while you clean the actual URLs in your code.
Q: Are protocol-relative URLs (//cdn.example.com/x.js) still recommended?
A: No. They were a 2010-era workaround for sites that served both HTTP and HTTPS. In 2026 you should serve everything as HTTPS-only and use absolute https:// URLs. Protocol-relative URLs make it harder to spot mixed content during code review and offer no benefit over explicit HTTPS.
Q: Does mixed content affect SEO rankings?
A: Indirectly but measurably. Google uses HTTPS as a ranking signal, Lighthouse flags mixed content under "Best Practices," and mixed content disqualifies a page from several "secure context" features that affect Core Web Vitals. It's not a hard penalty, but it's a quiet drag on your scores.
Q: How often should I check for mixed content?
A: Every deploy at minimum. Mixed content is reintroduced most often through CMS edits, marketing pixels, and third-party widget updates — none of which involve a code review. An automated weekly scan catches regressions before users see broken padlocks.
Conclusion
Mixed content is one of those issues that's easy to introduce, easy to miss, and easy to fix once you know where to look. The cost of getting it wrong — broken padlocks, blocked scripts, lost conversions, SEO drag — is wildly out of proportion to the effort required to prevent it.
The recipe is simple: detect with DevTools and an automated scanner, fix at the URL level, deploy upgrade-insecure-requests as a safety net, and re-scan on every deploy.
Start your free security scan on ZeriFlow → — find every mixed content issue across your entire site in 60 seconds, alongside 80+ other security checks. Free plan available, no credit card required.