Mixed Content: The page was loaded over HTTPS, but requested an insecure resource
What causes this
Your page is served over HTTPS but tries to load a resource (image, script, API call, font, iframe) over plain HTTP. Browsers block this because an attacker could intercept and modify the insecure resource, compromising the security of your HTTPS page.
There are two types:
- Active mixed content (scripts, iframes, fetch) — always blocked, breaks functionality
- Passive mixed content (images, audio, video) — may load with a warning, but some browsers block these too
Fix 1: Change HTTP URLs to HTTPS
The simplest fix — update the URLs:
<!-- ❌ HTTP -->
<img src="http://cdn.example.com/image.jpg" />
<script src="http://cdn.example.com/lib.js"></script>
<!-- ✅ HTTPS -->
<img src="https://cdn.example.com/image.jpg" />
<script src="https://cdn.example.com/lib.js"></script>
Fix 2: Use protocol-relative URLs
Let the browser match the page’s protocol:
<!-- Loads via HTTPS if page is HTTPS -->
<img src="//cdn.example.com/image.jpg" />
Note: protocol-relative URLs are considered legacy. Prefer explicit https:// instead.
Fix 3: Fix API calls in your code
// ❌ Hardcoded HTTP
fetch('http://api.example.com/data');
// ✅ Use HTTPS
fetch('https://api.example.com/data');
// ✅ Or use relative URLs for same-origin APIs
fetch('/api/data');
Fix 4: Add Content-Security-Policy header
Force all resources to load over HTTPS:
Content-Security-Policy: upgrade-insecure-requests
In your HTML:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
Or in your server config (Nginx):
add_header Content-Security-Policy "upgrade-insecure-requests" always;
This tells the browser to automatically upgrade HTTP requests to HTTPS. It’s a great safety net but shouldn’t replace actually fixing the URLs.
Fix 5: Find all mixed content on your site
Use browser DevTools or a crawler:
# Check the console in DevTools — mixed content warnings show the exact URLs
# Or use a crawler
npx is-website-vulnerable https://yoursite.com
In Chrome DevTools, the Console and Network tabs both flag mixed content requests.
Fix 6: Fix third-party embeds
Some embed codes default to HTTP:
<!-- ❌ Old embed code -->
<iframe src="http://maps.google.com/..."></iframe>
<!-- ✅ Updated -->
<iframe src="https://maps.google.com/..."></iframe>
If a third-party service doesn’t support HTTPS, you’ll need to find an alternative or proxy the resource through your own HTTPS server.
How to prevent it
- Always use
https://in your code — never hardcodehttp:// - Add
upgrade-insecure-requestsCSP header as a safety net - Use relative URLs (
/api/data) for same-origin resources - Test your site with browser DevTools console open after deploying
- Set up automated checks in CI to scan for
http://URLs in your codebase