TL;DR: Mixed content happens when an HTTPS page loads resources (images, scripts, stylesheets, iframes) over plain HTTP. Fix it by finding every HTTP reference in your HTML, CSS and JS and changing them to HTTPS — or using a Content-Security-Policy upgrade header to handle it automatically. Run a free Kalenfy scan to detect mixed content on your site without opening DevTools.
What mixed content actually breaks
Browsers treat mixed content as a security risk because an attacker on the same network can intercept and replace the HTTP resource — injecting scripts, changing images, or stealing form data — even though the page itself uses HTTPS.
| Type | Examples | Browser behaviour |
|---|---|---|
| Active mixed content | Scripts, stylesheets, iframes, XHR/fetch | Blocked by default — page may break |
| Passive mixed content | Images, audio, video | Loaded with a warning — padlock shows "Not secure" |
Either type removes the padlock, fails security header checks, and can cause Content-Security-Policy violations.
Step 1 — Find all mixed content
Browser DevTools (quick check)
- Open your site in Chrome or Firefox.
- Press F12 → Console tab.
- Look for warnings starting with "Mixed Content:" — each one names the HTTP URL that needs fixing.
- Click the Network tab → filter by "http://" to see all insecure requests.
Free scan (site-wide)
The Kalenfy scanner checks for mixed content across your page automatically — no DevTools required, no crawling configuration. It identifies which resources load over HTTP so you can fix them directly.
Searching your codebase
For custom sites, search your HTML, CSS and JS for http://
(not https://). In a terminal:
grep -r "http://" ./src --include="*.html" --include="*.css" --include="*.js"
Step 2 — Fix the references
Simple URL swap
The most direct fix: change every http:// to https://
in your source files. Works when the resource's server supports HTTPS — which almost
all CDNs, font services and third-party scripts do in 2026.
<!-- Before -->
<img src="http://example.com/logo.png">
<script src="http://cdn.example.com/lib.js"></script>
<!-- After -->
<img src="https://example.com/logo.png">
<script src="https://cdn.example.com/lib.js"></script>
Protocol-relative URLs
Use // instead of https:// — the browser uses whatever
protocol the page is loaded over. Useful for resources you don't control but that
support both HTTP and HTTPS:
<img src="//example.com/logo.png">
Self-host the resource
If the external server doesn't support HTTPS (rare but possible for old CDNs or self-hosted fonts), download the file and serve it from your own domain under HTTPS.
Step 3 — WordPress-specific fixes
WordPress is the most common source of mixed content because it stores absolute URLs
in the database. Pages, posts and widgets written when the site was on HTTP still
contain http://yourdomain.com references.
Plugin: Really Simple SSL
Really Simple SSL (free) automatically rewrites HTTP URLs to HTTPS on the fly and fixes mixed content from the database. Install via Plugins → Add New. It also sets the site URL and home URL to HTTPS in Settings → General.
Manual database update
If you prefer not to use a plugin, update the database directly using Search-Replace-DB or WP-CLI:
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables
Always take a database backup before running a search-replace.
Check the wp-config.php
Ensure these lines are in wp-config.php:
define('WP_HOME', 'https://yourdomain.com');
define('WP_SITEURL', 'https://yourdomain.com');
Step 4 — Use CSP upgrade-insecure-requests as a safety net
The upgrade-insecure-requests directive tells browsers to automatically
upgrade any HTTP sub-resource request to HTTPS before fetching it. It is a useful
safety net but should not replace fixing the source URLs — it doesn't work on
cross-origin navigation and some browser implementations have gaps.
Add this HTTP header on your server:
Content-Security-Policy: upgrade-insecure-requests
Or add a meta tag in the <head>:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
Step 5 — Verify the fix
- Reload your page — the browser padlock should show a closed lock with no warning.
- Check DevTools Console — no "Mixed Content:" warnings should appear.
- Re-run a Kalenfy scan — the mixed content check should now pass.
FAQ
My site is fully HTTPS but the padlock still shows "Not secure" — why?
Passive mixed content (images loading over HTTP) shows the "Not secure" label in some browsers without fully blocking the page. Check the Console for "Mixed Content:" warnings with "loaded over HTTP" in the message — those are the culprits.
Does mixed content affect SEO?
Indirectly. Google uses HTTPS as a ranking signal. A broken padlock or blocked active mixed content degrades user trust metrics (bounce rate, dwell time) and can trigger browser warnings that deter visitors. Fixing mixed content is part of any complete HTTPS migration.
I fixed the HTML but still see the warning — what else could it be?
Check CSS files for background-image: url('http://...'), inline styles
in the HTML, JavaScript that dynamically constructs HTTP URLs, and any third-party
scripts or widgets that load their own HTTP resources. Also clear browser cache before
re-testing.
My CDN serves the same image on both HTTP and HTTPS — do I still need to change it?
Yes. Even though the CDN supports HTTPS, the reference in your HTML says HTTP —
so the browser requests it over HTTP and flags it as mixed content. Change the
reference to https:// or //.