How to Fix Mixed Content Issues: HTTPS Security Guide 2026
Mixed content is one of the most common HTTPS security issues on the web. When your secure HTTPS page loads resources over insecure HTTP, browsers display warnings, block critical resources, and users see the dreaded "Not Secure" label. This guide covers exactly what mixed content is, the critical difference between active and passive types, how to find every occurrence, and how to fix it permanently using CSP headers and systematic URL updates.
TL;DR -- Quick Summary
- ✓ Mixed content = HTTP resources loaded on an HTTPS page, creating security vulnerabilities
- ✓ Active mixed content (scripts, iframes, CSS) is blocked by all modern browsers, breaking page functionality
- ✓ Passive mixed content (images, video, audio) triggers warnings and is auto-upgraded in Chrome 132+
- ✓ Fix by updating all
http://URLs tohttps://in HTML, CSS, JS, and database - ✓ Add
Content-Security-Policy: upgrade-insecure-requestsas a safety net
Active vs Passive Mixed Content -- Browser Behavior
Active Mixed Content
BLOCKED by browsers
<script src="http://..."><link href="http://..." rel="stylesheet"><iframe src="http://...">fetch("http://...")<object> / <embed>Can modify the DOM, steal data, inject malware. Browsers refuse to load these.
Passive Mixed Content
WARNING + auto-upgrade attempt
<img src="http://..."><audio src="http://..."><video src="http://..."><source src="http://...">CSS background-image: url(http://...)Cannot modify page. Browsers auto-upgrade to HTTPS; if that fails, content may not load.
Table of Contents
What Is Mixed Content?
Mixed content occurs when a webpage served over a secure HTTPS connection loads sub-resources (images, scripts, stylesheets, iframes, fonts, or media) over an insecure HTTP connection. The "mix" of secure and insecure content on the same page creates a security vulnerability that undermines the entire purpose of HTTPS encryption.
When a user visits https://yoursite.com/page, they expect every resource on that page to be encrypted. If even a single image loads from http://yoursite.com/photo.jpg, the page has mixed content. The encrypted connection is only as strong as its weakest link --- and that HTTP resource is an unencrypted, interceptable weak link.
According to the W3C Mixed Content specification, any resource request initiated from a secure context that targets a non-secure URL is classified as mixed content. The specification defines two severity levels --- optionally-blockable (passive) and blockable (active) --- which determine how browsers handle each case.
<!-- Page served over HTTPS -->
https://yoursite.com/page<!-- These HTTP resources cause mixed content -->
<img src="http://yoursite.com/photo.jpg"><script src="http://cdn.example.com/app.js"></script><link href="http://fonts.example.com/style.css" rel="stylesheet"><!-- These HTTPS resources are fine -->
<img src="https://yoursite.com/photo.jpg"><script src="https://cdn.example.com/app.js"></script>Security Risk: Man-in-the-Middle Attacks
A single HTTP resource is enough for an attacker to intercept and modify. A man-in-the-middle (MITM) attacker on the same network can replace an HTTP script with malicious code, swap an HTTP image for a phishing mockup, or inject tracking scripts --- all while the padlock icon gives users a false sense of security. The entire trust model of HTTPS depends on every single resource being encrypted.
Active vs Passive Mixed Content
Not all mixed content carries the same risk. Browsers categorize mixed content into two types based on the resource's ability to interact with and modify the page. Understanding this distinction is essential because browsers handle each type differently.
Active Mixed Content (Blocked by Browsers)
Active mixed content includes any HTTP resource that can access or modify the Document Object Model (DOM) of the page. These resources have full scripting access --- meaning an attacker who intercepts them could steal user credentials, inject malware, redirect form submissions, or take complete control of the page.
Resources classified as active mixed content:
<script src="http://...">--- JavaScript files that can execute arbitrary code<link rel="stylesheet" href="http://...">--- CSS that can modify layout and content visibility<iframe src="http://...">--- Embedded frames with their own execution contextXMLHttpRequest/fetch()to HTTP URLs --- AJAX requests that can send and receive data<object>and<embed>--- Plugin content with execution capabilities
Since Chrome 79 (released December 2019), all modern browsers block active mixed content by default. This means the resource simply does not load. If your page depends on an HTTP script, the script will not execute, and your page functionality will break silently. Users will not see an error page --- they will see a partially broken page with missing interactivity, unstyled elements, or empty sections.
Passive Mixed Content (Warning + Auto-Upgrade)
Passive (also called "optionally-blockable") mixed content includes HTTP resources that cannot directly modify the page. While they cannot execute scripts or change the DOM, they can still be intercepted --- an attacker could replace an image with misleading content or track which pages a user visits.
Resources classified as passive mixed content:
<img src="http://...">--- Images (the most common source of passive mixed content)<audio src="http://...">--- Audio files<video src="http://...">--- Video files<source>--- Media source elements inside <audio> or <video>
Starting with Chrome 80+, browsers automatically attempt to upgrade passive mixed content from HTTP to HTTPS. If the HTTPS version of the resource exists, it loads successfully. If it does not exist or returns an error, the resource fails to load entirely --- resulting in broken images or missing media on your page.
| Characteristic | Active Mixed Content | Passive Mixed Content |
|---|---|---|
| Can modify page? | Yes (full DOM access) | No (display only) |
| Browser behavior | Blocked entirely | Auto-upgraded to HTTPS |
| User sees | Broken functionality | Missing image or warning icon |
| Risk level | Critical (code execution) | Moderate (content spoofing) |
| Common examples | Scripts, CSS, iframes | Images, video, audio |
| Console message | Blocked loading mixed active content | Mixed Content warning |
Why Mixed Content Matters for SEO
Mixed content has both direct and indirect effects on your search engine rankings. Google has confirmed HTTPS as a ranking signal since 2014, and the impact has only grown since. Here is exactly how mixed content hurts your SEO performance:
1. Chrome's "Not Secure" Warning Destroys User Trust
When mixed content is detected, Chrome changes the padlock icon to a warning indicator or displays "Not Secure" in the address bar. According to a Google Transparency Report, over 95% of Chrome traffic now uses HTTPS --- meaning users have come to expect the padlock. Seeing a security warning causes immediate distrust, increasing bounce rates by 10-20% according to industry studies.
Browser Address Bar -- HTTPS vs Mixed Content
Secure Connection
https://yoursite.com/page
Mixed Content Detected
https://yoursite.com/page
Not Secure
https://yoursite.com/page
2. Blocked Resources Break Core Web Vitals
When active mixed content is blocked, scripts and stylesheets fail to load. This can break page rendering entirely, causing Largest Contentful Paint (LCP) to spike above 2.5 seconds as the browser waits for resources that will never arrive. Missing CSS can cause massive Cumulative Layout Shift (CLS) as elements render unstyled and then reflow. Both metrics are Core Web Vitals that directly influence your ranking position.
3. HTTPS Is a Confirmed Ranking Signal
Google confirmed HTTPS as a lightweight ranking signal in 2014, and its weight has increased over the years. A site with mixed content does not fully satisfy the HTTPS ranking signal --- the page is technically HTTPS, but its security is compromised. Google's crawlers note mixed content issues, and sites with widespread mixed content may see their HTTPS ranking boost diminished.
4. Mobile-First Indexing Amplifies the Problem
Since Google uses 100% mobile-first indexing (as of July 2024), the mobile version of your page is what gets evaluated. Mobile browsers enforce mixed content policies identically to desktop. If your mobile pages have mixed content that breaks functionality or displays warnings, your rankings suffer across both mobile and desktop results.
How to Find Mixed Content on Your Site
Before fixing mixed content, you need to identify every occurrence. There are three effective methods, and you should use all three for comprehensive coverage:
Method 1: Browser Developer Console
The fastest way to check a single page is the browser console. Open your HTTPS page in Chrome and press F12 to open DevTools. Check the Console tab for yellow or red mixed content warnings:
Mixed Content: The page at 'https://yoursite.com/page' was loaded over HTTPS, but requested an insecure image 'http://yoursite.com/photo.jpg'. This content should also be served over HTTPS.
Mixed Content: The page at 'https://yoursite.com/page' was loaded over HTTPS, but requested an insecure script 'http://cdn.example.com/analytics.js'. This request has been blocked; the content must be served over HTTPS.
Yellow warnings indicate passive mixed content (images, media). Red errors indicate active mixed content (scripts, CSS) that has been blocked. Each message includes the exact URL of the insecure resource, making it easy to find and fix.
Method 2: InstaRank SEO Site Audit
For a complete site-wide check, use InstaRank SEO's free audit tool. It crawls every page on your site and identifies all mixed content issues categorized by type: mixed scripts, mixed stylesheets, mixed images, mixed iframes, mixed forms, and other mixed resources. Each issue includes the exact resource URL and the page it appears on, so you can fix them systematically.
Method 3: Source Code Search
Search your codebase directly for HTTP URLs. This catches mixed content in templates, theme files, and JavaScript that might not appear until runtime:
# Search HTML, CSS, and JS files for http:// URLs
grep -rn "http://" --include="*.html" --include="*.css" --include="*.js" --include="*.tsx" .
# For WordPress, also check the database
SELECT post_title, post_name FROM wp_posts WHERE post_content LIKE '%http://%';
Step-by-Step Fix: Eliminating Mixed Content
Follow these steps in order. Each step targets a different source of mixed content, from the most impactful (your own HTML templates) to the hardest to catch (third-party scripts and database content).
- 1
Update hardcoded HTTP URLs in HTML templates
Search every template, partial, and layout file for src="http:// and href="http:// attributes. Change each to https://. This catches the majority of mixed content on most sites.
- 2
Fix HTTP URLs in CSS files
Check all stylesheets for background-image: url(http://...), @font-face src, and @import rules pointing to HTTP. CSS mixed content is classified as active, so browsers will block these entirely.
- 3
Update JavaScript files and AJAX calls
Review scripts for fetch(), XMLHttpRequest, or dynamically created elements that load HTTP resources. These are active mixed content and will be blocked, breaking functionality.
- 4
Fix third-party embeds and widgets
Update embed codes from YouTube, maps, social widgets, and analytics scripts. Most providers now offer HTTPS by default, but old embed codes may still use HTTP. Get fresh embed codes from each provider.
- 5
Use relative URLs for internal resources
For resources on your own domain, switch from absolute URLs to relative paths: /images/photo.jpg instead of http://yoursite.com/images/photo.jpg. This eliminates protocol issues entirely.
- 6
Verify each fix in the browser console
After each change, reload the page with DevTools open and confirm the mixed content warning is gone. Check both desktop and mobile viewports, as some resources may only load conditionally.
// BEFORE --- Mixed content issues
<img src="http://yoursite.com/hero.jpg" alt="Hero"><script src="http://cdn.example.com/lib.js"></script><link href="http://fonts.googleapis.com/css" rel="stylesheet">// AFTER --- All resources over HTTPS
<img src="/images/hero.jpg" alt="Hero"><script src="https://cdn.example.com/lib.js"></script><link href="https://fonts.googleapis.com/css" rel="stylesheet">Important: Protocol-Relative URLs Are Deprecated
You may see advice to use protocol-relative URLs like //example.com/file.js. While these technically work, they are no longer recommended. Paul Irish (who originally popularized the pattern) reversed his recommendation in 2014. Since all modern sites should be HTTPS, always use explicit https:// URLs. Protocol-relative URLs can cause double downloads and caching issues.
Fixing Mixed Content in WordPress
WordPress sites are especially prone to mixed content because URLs are stored in the database. When you migrate from HTTP to HTTPS, your theme files update, but the thousands of http:// URLs embedded in post content, widget settings, and options remain unchanged. Here is how to fix them:
Option 1: Use a Plugin (Recommended for Non-Developers)
The Really Simple SSL plugin automatically detects and fixes mixed content by rewriting HTTP URLs to HTTPS on the fly. It handles database content, theme files, and third-party resources without manual intervention. Over 5 million WordPress sites use this approach. After activating, check your browser console to confirm all mixed content is resolved.
Option 2: Database Search-and-Replace (Permanent Fix)
For a permanent fix, update the URLs directly in the database. Use the Better Search Replace plugin or WP-CLI to safely replace all http://yoursite.com with https://yoursite.com:
wp search-replace 'http://yoursite.com' 'https://yoursite.com' --all-tables --dry-run
# Review results, then run without --dry-run to apply
wp search-replace 'http://yoursite.com' 'https://yoursite.com' --all-tables
Option 3: Manual SQL Queries (Advanced)
If you cannot use plugins or WP-CLI, execute these SQL queries directly (always back up first):
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://yoursite.com', 'https://yoursite.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://yoursite.com', 'https://yoursite.com');
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://yoursite.com', 'https://yoursite.com');
WordPress Settings to Verify
After fixing database content, go to Settings > General and confirm both "WordPress Address (URL)" and "Site Address (URL)" use https://. If these are set to HTTP, WordPress will generate HTTP URLs for every internal link, stylesheet, and script across your entire site.
Content Security Policy as a Defense Layer
Content Security Policy (CSP) is an HTTP header that gives you fine-grained control over what resources your page can load and from where. For mixed content, the most important directive is upgrade-insecure-requests, which tells the browser to automatically upgrade all HTTP requests to HTTPS before sending them.
Content Security Policy: upgrade-insecure-requests Flow
Browser requests
http://cdn/img.jpg
CSP Header Active
upgrade-insecure-requests
Rewrites HTTP to HTTPS before the network request is sent
Actual request sent
https://cdn/img.jpg
Adding the CSP Header
You can add the upgrade-insecure-requests directive as either an HTTP response header or an HTML meta tag:
Content-Security-Policy: upgrade-insecure-requests;
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
Server Configuration Examples
Header always set Content-Security-Policy "upgrade-insecure-requests;"
add_header Content-Security-Policy "upgrade-insecure-requests;" always;
headers: async () => [{
source: '/(.*)',
headers: [{ key: 'Content-Security-Policy', value: 'upgrade-insecure-requests;' }],
}]
CSP Is a Safety Net, Not a Fix
upgrade-insecure-requests only works if the HTTPS version of the resource exists. If a CDN or third-party server does not support HTTPS, the upgraded request will fail and the resource will not load. Always fix the source URLs first, and use CSP as an additional safety layer for any resources you might have missed.
Additional CSP Defenses
Beyond upgrade-insecure-requests, consider implementing block-all-mixed-content as a strict alternative. This directive tells the browser to block all mixed content (both active and passive) rather than attempting to upgrade it:
Content-Security-Policy: block-all-mixed-content;
Use block-all-mixed-content only after you are confident all resources have been migrated to HTTPS. Otherwise, you may break images and media that would have loaded successfully with the upgrade directive. For most sites, upgrade-insecure-requests is the better choice during the migration period.
HSTS: Enforcing HTTPS at the Transport Layer
HTTP Strict Transport Security (HSTS) complements CSP by telling browsers to never connect to your site over HTTP. Once a browser receives the HSTS header, it will automatically use HTTPS for all future requests to your domain, even if the user types http:// in the address bar:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Before vs After: Mixed Content Audit Results
Before Fix
After Fix
Fix Mixed Content on Your Site Today
Run a free audit with InstaRank SEO to find every mixed content issue across your entire site. Get a detailed report with exact URLs, resource types, and prioritized fixes --- all in under 60 seconds.
Run Free Mixed Content Audit →