What Mixed Content Actually Means
Mixed content happens when an HTTPS page loads subresources (scripts, stylesheets, images, fonts, iframes, XHR responses) over plain HTTP. The parent document is encrypted, the subresource is not, and the browser has to decide what to do about it. That decision usually involves either silently blocking the request or showing a warning that scares your users into closing the tab.
The technical definition lives in the W3C Mixed Content spec, but the practical reality is simpler. If your page is served from https://example.com and it tries to load http://cdn.legacy.com/script.js, you have a problem. The connection to the CDN is unencrypted, which means anyone on the network path can read it, modify it, or inject their own JavaScript. The browser cannot guarantee the integrity of your page anymore, so it stops pretending the lock icon means anything.
A mixed content checker scans your page, parses every resource URL it requests (including ones loaded dynamically via JavaScript), and flags anything still using http://. The good ones also check resources loaded inside iframes, fonts referenced from CSS, and image URLs hidden inside JSON-LD schema blocks. Surface-level scanners miss those, which is why a clean Lighthouse report does not always mean a clean site.
Why Browsers Block Mixed Content (Active vs Passive)
Browsers split mixed content into two buckets, and the distinction matters because they behave very differently. Active mixed content is anything that can change the behavior of the page: scripts, stylesheets, iframes, XHR/fetch requests, web workers, service workers, and the like. If an attacker injects code into one of these, they can rewrite the DOM, steal session tokens, redirect the user, or do basically anything they want. So browsers refuse to load it, period.
Passive mixed content is stuff that displays but cannot execute: images, audio, video, and a few legacy element types. The risk is lower because a malicious image cannot hijack your page (mostly), but it can still leak referrer data and let a network attacker know what content the user is viewing. Browsers used to load this passively with a yellow warning. Chrome 81 and later auto-upgrade most of these to HTTPS first, and if that fails, they get blocked in some contexts too.
The line between active and passive has been moving toward "block everything" for years. If you assume any HTTP subresource will eventually be blocked, you will save yourself a future incident. The browsers are not going to relax these rules; they are going to tighten them.
What Gets Hard-Blocked Right Now
Active mixed content is blocked outright in every major browser. Scripts loaded from HTTP origins on an HTTPS page will not run, and the browser console shows a clear error like Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure script. Same for stylesheets, web workers, and iframe sources. Your page will render, but anything that depended on those resources is broken.
Fetch and XHR requests to HTTP endpoints are also blocked, which tends to cause the most confusing bugs. The page loads, the UI looks fine, but every API call returns a network error. Developers who do not check the console assume the backend is down. The backend is fine; the browser just refused to talk to it over an unencrypted channel from a secure context.
WebSocket connections follow the same rule. ws:// from an HTTPS page is blocked, you have to use wss://. This catches a lot of legacy realtime systems that worked fine when the site was still HTTP and silently broke during the migration.
What Slips Through With a Warning
Images, audio, and video can still load over HTTP in passive contexts, but the browser strips the lock icon and shows a "Not fully secure" indicator instead. On Chrome and Edge, the address bar shows an info icon with a warning when you click it. On Safari, you get a similar treatment with slightly different wording. On Firefox, the lock gets a yellow exclamation triangle.
Users notice. They might not know what mixed content is, but they know the lock used to be solid green and now it is not. Conversion rates drop on checkout pages with mixed content warnings. Sign-up forms see more abandonment. The warning does not have to say "this site might steal your data" for users to feel uneasy and bounce.
How Mixed Content Hurts SEO
Google has been clear that HTTPS is a ranking signal since 2014, and the modern Core Web Vitals stack assumes a fully secure context. A page with mixed content technically still serves over HTTPS, so it does not lose the HTTPS bonus, but the broken subresources cause real ranking damage in other ways. If your hero image is an HTTP URL that gets blocked, your Largest Contentful Paint metric tanks. If a CSS file is blocked, Cumulative Layout Shift goes through the roof. If a critical script fails, the page might never reach interactive at all.
There is also the trust signal angle. Search Quality Raters are explicitly told to penalize sites that look "broken or untrustworthy," and a page where half the images do not load fits that description. Even if Googlebot itself loads the resources fine (it ignores most mixed content warnings during crawl), the user experience signals it derives from real Chrome users will reflect the problem.
Where Mixed Content Comes From
The usual suspects are predictable. Legacy CDN URLs hardcoded into your codebase from before the HTTPS migration. CMS databases with absolute image URLs starting with http://yoursite.com. Third-party embed scripts from analytics or chat widgets that have not updated to HTTPS. Old YouTube embeds using the protocol-specific URL form. Newsletter signup widgets from vendors who went out of business in 2017. RSS feeds that link out to HTTP resources.
WordPress sites are particularly bad because the database stores absolute URLs in post content, and a simple search-replace on the SQL dump usually fixes it. Headless CMSes can have similar issues if editors paste HTTP image URLs into rich text fields. Custom-built sites tend to get bitten by hardcoded staging environment URLs that pointed to HTTP and never got updated.
The Quick Fix: upgrade-insecure-requests
The Content-Security-Policy directive upgrade-insecure-requests tells the browser to automatically rewrite any http:// URL on your page to https:// before fetching it. Add the header Content-Security-Policy: upgrade-insecure-requests and most of your mixed content problems vanish overnight, assuming the destination servers actually support HTTPS.
The catch is that this is a band-aid, not a fix. If the upgraded request fails (because the third-party server only speaks HTTP), the resource just does not load, the same as if it were blocked. You also lose visibility; the browser stops complaining, so you stop noticing the problem. New mixed content gets added to the codebase and you never see the warnings.
The Systematic Fix and the AI Crawler Angle
The real fix is methodical: audit every URL with a mixed content checker, fix the source (database, codebase, CMS), and set 301 redirects on the HTTP versions of any domains you control. Replace third-party widgets with HTTPS-native alternatives. For embeds you cannot control, vendor the asset onto your own HTTPS domain. Add a CSP report-uri so you get notified when new mixed content sneaks in.
AI crawlers (Perplexity, ChatGPT, Claude) handle mixed content roughly the way a strict browser does: they render the page, see the broken subresources, and frequently conclude the page is malformed. If your product images do not load for the AI, your product will not show up in AI search results. Mixed content used to be a nuisance; now it is an AI visibility issue too, and it is one of the easier wins on the technical SEO checklist.
Why a Clean Lighthouse Score Can Still Hide Mixed Content
A page can pass Lighthouse and a casual manual review and still ship insecure requests, because the worst offenders only appear under conditions a quick scan never triggers. Resources injected by JavaScript after a user interaction, assets loaded inside a third-party iframe, fonts pulled in from deep inside a stylesheet, and image URLs buried in a JSON-LD schema block all live outside the initial render that most scanners inspect. The page looks secure on load and then quietly fires an insecure request the moment someone clicks a tab, opens a gallery, or scrolls a lazy-loaded section into view.
The other blind spot is environment-specific. Mixed content frequently depends on which CMS template rendered the page, which means your homepage and your top landing page can be perfectly clean while a particular blog layout or a legacy product template leaks HTTP image URLs on every page that uses it. Checking one URL and declaring the site fixed is how teams reopen the same incident a month later. A thorough mixed content checker parses dynamically loaded resources and inspects the templated corners, which is exactly where a green Lighthouse badge gives false confidence.
Treat any tool that only reads the raw HTML as a first pass, not a verdict. The resources that get blocked and break a page are disproportionately the ones added at runtime, so a scan that ignores rendered and interaction-triggered requests is checking the safest part of the page and skipping the dangerous part.
A Repeatable Workflow to Find, Fix, and Keep It Fixed
The reliable workflow has three stages: find every insecure request, fix it at the source, and install a tripwire so new mixed content cannot creep back in unnoticed. Finding means scanning a representative URL from each template, not just the homepage, and including pages with galleries, embeds, and interactive widgets where runtime requests hide. Fixing means going to the origin of the URL rather than patching symptoms: a database search-and-replace for absolute HTTP links stored in post content, a code change for hardcoded asset URLs, and a vendor swap for any third-party widget that still only speaks HTTP.
For domains you control, add a 301 from the HTTP version of each asset to its HTTPS equivalent so older references upgrade themselves. For assets you cannot control, the durable answer is to host the file on your own HTTPS domain rather than depending on a third party to modernize. The upgrade-insecure-requests policy is worth keeping in place as a safety net, but treat it as a net and not a fix, because it hides the warnings you actually want to see when something new breaks.
The keeping-it-fixed stage is what most sites skip and later regret. A Content-Security-Policy report endpoint will notify you the moment a page requests an insecure resource, turning a silent regression into an alert you can act on the same day. Pair that with a periodic re-scan after major releases and content imports, since a bulk migration or a pasted batch of legacy URLs is the most common way a freshly cleaned site quietly slides back into mixed content.