Mixed content occurs when an HTTPS page loads resources (images, scripts, styles) over HTTP. The browser considers this unsafe and blocks it or warns the user.
Types of mixed content
| Type | What it includes | Browser action |
|---|---|---|
| Active Mixed Content | JS, CSS, iframes | Blocks automatically |
| Passive Mixed Content | Images, audio, video | Shows a warning |
How to find mixed content
Chrome DevTools
F12 → Console
Look for: "Mixed Content: The page ... was loaded over HTTPS"
Or: "blocked:mixed-content" in Network
Online tools
- Why No Padlock — whynopadlock.com
- SSL Checker — ssllabs.com
Fixing it in WordPress
Method 1: Really Simple SSL plugin
Install the Really Simple SSL plugin — it automatically replaces HTTP with HTTPS in the content and settings.
Method 2: wp-config.php
define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS'] = 'on';
Method 3: WP-CLI
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# Make sure everything is correct, then:
wp search-replace 'http://example.com' 'https://example.com' --all-tables
Fixing it via .htaccess
# Redirect all HTTP to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Upgrade-Insecure-Requests header
Header always set Content-Security-Policy "upgrade-insecure-requests"
upgrade-insecure-requests header is the fastest way to fix passive mixed content without changing the content.Mixed content messages explained
The exact text in the browser console or PHP log tells you what is broken and why.
Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure image 'http://...'. This content should also be served over HTTPS.— passive content: the browser loads the image but shows a warning and drops the green padlock.Mixed Content: ... requested an insecure script '...'. This request has been blocked; the content must be served over HTTPS.— active content: the script never loads at all, and the page can break visually or functionally.- A
(blocked:mixed-content)status in the Network tab's Status column — the request was blocked before it was even sent, unlike a normal server error. Notice: unserialize(): Error at offset 61 of 89 bytes in ...— a typical symptom after a manualUPDATE ... REPLACE(...)on a WordPress database: a raw replace changes the string length inside serialized data, and PHP stores that length inside the value itself, so unpacking breaks.- Chrome's address bar shows "Not Secure" instead of a padlock, with "Your connection to this site is not fully secure" in the dropdown: the browser has already spotted at least one insecure resource on the page.
Fix methods: when to use which
| Method | When to use it | Limitation | Rollback |
|---|---|---|---|
| Really Simple SSL plugin | You need a fast fix on a live site with no database access | Rewrites output on the fly, does not fix links stored in the database | Disabling the plugin brings the http links back on screen |
| Constants in wp-config.php | The admin panel or login generates http links because of a proxy or CDN in front of the site | Does not touch links inside post content or widgets | Safe, these are just PHP constants |
| wp search-replace | You need a permanent fix for links in content, metadata, and settings | Requires a database backup before running | Changes the database, check first with the --dry-run flag |
| Manual SQL REPLACE | Not recommended for WordPress | Breaks serialized data, hence the unserialize error | Rollback is hard, only from a backup |
When these methods will not help
- If a CDN or reverse proxy sits in front of the site and itself talks to the backend over HTTP, the proxy is what creates the mixed content, not WordPress, and the fix belongs in the
X-Forwarded-Protoheader and the proxy's own configuration. - An embedded third-party widget, such as an iframe from a domain that has not issued itself an HTTPS certificate yet, cannot be fixed from your side until that third-party service moves to HTTPS on its own.
- Rules in
.htaccessonly work on Apache; on an Nginx backend the same redirect has to be written inside aserver {}block using Nginx syntax — .htaccess is not read there at all. upgrade-insecure-requestswill not help if the resource is not reachable over HTTPS at all: the browser will honestly try to switch and get a connection refusal instead of a warning.
Verifying that mixed content is really gone
# Find remaining http links in the database without making changes
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# Confirm the server is sending the expected security headers
curl -I https://example.com | grep -i content-security-policy
After fixing, open the page in a private window (to rule out caching) and open DevTools → Console — there should be no lines containing Mixed Content, and the padlock in the address bar should be closed with no warnings.
Frequently asked questions
How do you fix mixed content on a site that isn't built on WordPress?
The fixing principle is the same regardless of platform: find every absolute link pointing to a resource over the unencrypted protocol and replace it with the secure one, or with a protocol-relative path instead. The difference is just the tool — instead of a platform-specific plugin, the fix goes directly into templates, build configuration, or a project-wide source search.
Can a browser be temporarily told to allow insecure content so work isn't blocked while the cause is being tracked down?
Allowing insecure content to load can be switched on in a single browser's settings for one tab — that only lifts the block locally and does not fix the site for other visitors. This mode suits diagnosis only, showing how the page looks without blocked scripts and which resource is causing trouble, not as a lasting fix.
Does mixed content affect a site's search rankings?
Search engines don't apply a direct penalty for the mere presence of mixed content, but the insecure-connection warning lowers visitor trust and hurts behavioral signals — more bounce and less time on page get factored into ranking indirectly. Blocked scripts and styles can also break the layout or functionality, which affects how an algorithm perceives the page.
What should be done when HTTP links are hidden inside CSS rather than in HTML or the database?
Links inside CSS files, set through the url() rule for background images or fonts, need a separate search from database content — those files sit on the server and aren't touched by automatic link replacement in posts. Fix them by hand or with a bulk search, then clear the browser and CDN cache, or the old file keeps loading.