Skip to main content
Blog|
How-to guides

Mixed content error in WordPress: how to fix it

|
Mar 24, 2026|15 min read
HOW-TO GUIDESMixed content error inWordPress: how to fix itHOSTNEYhostney.comMarch 24, 2026

The mixed content error is one of those problems that makes your site look broken even though it technically loads. Your pages come up, your text is readable, but images are missing, styles are not applied, scripts fail silently, and the browser shows a warning instead of the padlock icon in the address bar. The site has an SSL certificate, the URL says HTTPS, but something on the page is still being loaded over plain HTTP. That mismatch is what browsers call “mixed content,” and they increasingly refuse to tolerate it.

The error does not crash your site, but it does damage it. Visitors see security warnings. Google penalizes sites without a fully secure connection. Some browsers block the insecure resources entirely, which means parts of your page simply disappear. The fix is straightforward once you understand where the HTTP references are coming from, but you often need to check several places because mixed content rarely has a single source.

What the error actually means#

When a browser loads a page over HTTPS, it expects every resource on that page to also be loaded over HTTPS. Every image, stylesheet, JavaScript file, font, iframe, and video source must use a secure connection. If even one resource is requested over plain HTTP, the browser flags the entire page as mixed content.

There are two types of mixed content, and browsers treat them differently:

Mixed passive content (also called “optionally blockable”) includes images, audio, and video loaded over HTTP. Most browsers still load these resources but remove the padlock icon and may show a warning in the console. The page works, but it looks insecure.

Mixed active content includes scripts, stylesheets, iframes, and fetch/XMLHttpRequest calls loaded over HTTP. Browsers block these entirely because a script loaded over an insecure connection could be intercepted and modified by an attacker. When active mixed content is blocked, your page loses functionality – JavaScript features stop working, CSS does not load, and embedded content disappears.

The distinction matters because passive mixed content might go unnoticed for months (the page looks fine except for the missing padlock), while active mixed content breaks things visibly.

You can see these errors in your browser’s developer tools console. They look like this:

Mixed Content: The page at 'https://example.com/about/' was loaded over HTTPS,
but requested an insecure image 'http://example.com/wp-content/uploads/photo.jpg'.
This request has been blocked; the content must be served over HTTPS.

Every mixed content error tells you exactly which resource is the problem and where it is being loaded from. That is your starting point for fixing it.

Cause 1: Hardcoded HTTP URLs in the database#

This is the most common cause of mixed content in WordPress, especially after migrating a site from HTTP to HTTPS or moving it from one domain to another. WordPress stores full URLs in the database – in post content, widget text, custom fields, menu items, theme options, and serialized plugin settings. If those URLs were saved as http:// before you installed your SSL certificate, they stay that way until someone changes them.

Every image you inserted into a post through the media library has its full URL stored in the wp_posts table. If you uploaded 500 images when the site was running on HTTP, you now have 500 hardcoded http:// URLs in your content.

How to diagnose

Open any page that shows the mixed content warning and look at the browser console in developer tools (F12, then the Console tab). The errors will point to specific URLs. If those URLs point to your own domain with http:// and the resources are things like uploaded images or media files, the source is almost certainly the database.

You can also check the Network tab in developer tools. Filter by “Mixed content” or look for requests with the scheme http:// on a page loaded over https:// . If the failing resources are in /wp-content/uploads/ , the URLs are stored in post content.

To confirm the scope of the problem, search the database directly if you have WP-CLI access:

wp db search 'http://yourdomain.com' --all-tables

This shows every occurrence of the HTTP URL across all tables, so you can see how widespread the problem is.

How to fix

Using WP-CLI (recommended):

wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables --dry-run

The --dry-run flag shows you what would change without actually changing anything. Review the output, and if it looks right, run it again without the flag:

wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables

WP-CLI’s search-replace is the best tool for this job because it correctly handles serialized data. WordPress plugins store settings as serialized PHP arrays in the wp_options table. If you do a raw SQL find-and-replace, you will break the serialization checksums and corrupt the data. WP-CLI deserializes, replaces, and re-serializes correctly.

If you do not have WP-CLI access:

The Better Search Replace plugin does the same thing from the WordPress admin. Install it, enter the old HTTP URL and the new HTTPS URL, select all tables, run a dry run first, then run the actual replacement.

What to watch for:

Run the search-replace for both http://yourdomain.com and http://www.yourdomain.com if your site has ever been accessible with the www prefix. Also check for any previous domain names if the site was migrated.

After running the replacement, clear any caching layers – page cache, object cache, CDN cache, and browser cache. Cached pages will still have the old HTTP URLs until the cache expires or is flushed.

Cause 2: Theme or plugin loading assets over HTTP#

Some themes and plugins have hardcoded http:// URLs in their PHP files, CSS, or JavaScript. This is a code problem, not a database problem, so a search-replace on the database will not fix it. The HTTP URLs are baked into the source files themselves.

This is more common with older themes, themes purchased from less reputable marketplaces, and free plugins that have not been updated in years. Well-maintained themes and plugins use protocol-relative URLs ( //example.com/style.css ) or WordPress functions like get_stylesheet_directory_uri() that automatically use the correct protocol.

How to diagnose

The browser console and Network tab are your primary tools here. Look at the URLs that are failing – if they point to files inside /wp-content/themes/ or /wp-content/plugins/ , the theme or plugin code is the source.

To find the exact file, use grep on the server:

# Search theme files for hardcoded HTTP URLs
grep -r 'http://' wp-content/themes/your-theme/ --include='*.php' --include='*.css' --include='*.js'

# Search plugin files
grep -r 'http://' wp-content/plugins/ --include='*.php' --include='*.css' --include='*.js'

Be prepared for a lot of output. Not every http:// string is a problem – URLs in comments, documentation strings, and protocol detection code are fine. Focus on URLs that appear in src= , href= , url() , wp_enqueue_script() , or wp_enqueue_style() calls.

How to fix

If the theme or plugin is actively maintained, update it. Most developers fixed hardcoded HTTP URLs years ago. If you are running an outdated version, the fix might already exist.

If you need to fix it manually, replace http:// with https:// or, better yet, with protocol-relative URLs // in the affected files. But do this in a child theme or custom plugin – editing a theme or plugin directly means your changes will be overwritten on the next update.

For enqueued scripts and styles in functions.php , the correct approach is to use WordPress functions:

// Bad - hardcoded protocol
wp_enqueue_style('custom', 'http://example.com/css/custom.css');

// Good - protocol follows the site URL
wp_enqueue_style('custom', get_stylesheet_directory_uri() . '/css/custom.css');

If the theme or plugin is abandoned, consider replacing it. A theme that still has hardcoded HTTP URLs in 2026 is likely to have other issues too, including security vulnerabilities. This type of problem often shows up alongside other common WordPress errors caused by outdated code.

Cause 3: External resources loaded over HTTP#

Your site might be loading resources from third-party services over HTTP. Common culprits include Google Fonts loaded via http://fonts.googleapis.com , JavaScript libraries pulled from old CDN links, embedded iframes from services that have not upgraded to HTTPS, and tracking pixels from analytics platforms.

This is different from Causes 1 and 2 because the resource is not on your server. You cannot fix it by changing files or running a database search-replace (unless the external URL happens to be stored in the database).

How to diagnose

Same approach: browser developer tools, Console and Network tabs. The URLs that show mixed content warnings will point to external domains rather than your own. Common patterns:

  • http://fonts.googleapis.com/css?family=...
  • http://code.jquery.com/jquery-3.x.min.js
  • http://player.vimeo.com/video/...
  • http://maps.google.com/maps?...

Check where these URLs are coming from. They could be in your theme files, plugin settings, widget content, or hardcoded in individual posts.

How to fix

Most major services support HTTPS. Simply changing http:// to https:// in the URL usually works:

  • https://fonts.googleapis.com/css?family=...
  • https://code.jquery.com/jquery-3.x.min.js
  • https://player.vimeo.com/video/...

If the URLs are in the database (widget content, post content), the WP-CLI search-replace from Cause 1 can handle them. If they are in theme or plugin files, the approach from Cause 2 applies.

If the external service does not support HTTPS at all, you have three options: host the resource locally over HTTPS, find an alternative service that supports HTTPS, or remove the resource entirely. In 2026, any service that does not support HTTPS is not one you want loading on your pages anyway.

For embedded iframes, the fix is usually updating the embed URL. Many embed codes that were copied years ago used HTTP, but the same service now supports HTTPS. Re-copy the embed code from the service and it will likely use HTTPS by default.

Cause 4: WordPress or wp-config.php not forcing HTTPS#

Even if you have an SSL certificate installed and your site loads over HTTPS, WordPress might not know that. If the Site URL and WordPress URL in the database still use http:// , WordPress generates internal links and asset URLs with the wrong protocol.

This is a configuration issue rather than a content issue, and it can cause mixed content across the entire site rather than on specific pages.

How to diagnose

Check the WordPress URL settings. If you can access the admin dashboard, go to Settings and then General. Look at “WordPress Address (URL)” and “Site Address (URL).” Both should start with https:// .

If you cannot access the admin, check the database directly:

wp option get siteurl
wp option get home

Both values should use https:// . If either one shows http:// , that is the problem.

Also check wp-config.php for any explicit URL definitions:

grep -i 'WP_HOME\|WP_SITEURL\|FORCE_SSL' wp-config.php

How to fix

Update the site URLs:

wp option update siteurl 'https://yourdomain.com'
wp option update home 'https://yourdomain.com'

Or add these lines to wp-config.php (which overrides the database values):

define('WP_HOME', 'https://yourdomain.com');
define('WP_SITEURL', 'https://yourdomain.com');

Force SSL for the admin area:

define('FORCE_SSL_ADMIN', true);

If your site is behind a reverse proxy or load balancer, WordPress might not detect HTTPS correctly because the proxy terminates SSL and forwards the request to WordPress over HTTP. In that case, add this to wp-config.php before the “That’s all, stop editing!” comment:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

This tells WordPress to trust the X-Forwarded-Proto header from the proxy. Without this, WordPress thinks every request is HTTP and generates HTTP URLs for everything.

Be careful with this configuration. If done incorrectly, you can create redirect loops. If you start seeing infinite redirects after making these changes, check Too many redirects error in WordPress: how to fix it for the resolution.

After updating the URLs, you still need to run the database search-replace from Cause 1 to fix all the existing content that was saved with HTTP URLs.

Cause 5: CSS background images and inline styles with HTTP URLs#

This is a subset of the database and code problems, but it deserves its own section because it is easy to miss. Background images set via CSS (either in stylesheet files or in inline styles on HTML elements) can contain HTTP URLs that do not show up when you scan post content.

Inline styles are particularly sneaky. Many page builders and visual editors write styles directly into the HTML:

<div style="background-image: url('http://example.com/wp-content/uploads/hero.jpg');">

These inline styles are stored in the database as part of post content, but they look different from regular image embeds, so they are easy to overlook.

How to diagnose

The browser Network tab is the best tool here. Filter requests by type (images) and look for HTTP requests. The Initiator column tells you which CSS file or HTML element triggered the request.

For CSS files, grep your theme’s stylesheets:

grep -r "http://" wp-content/themes/your-theme/ --include='*.css'

For inline styles in the database, search specifically for the url( pattern:

wp db search "url('http://" --all-tables
wp db search 'url("http://' --all-tables
wp db search "url(http://" --all-tables

Page builders like Elementor, Divi, and WPBakery store layout data as serialized arrays in post meta. Background images set through these builders are buried in serialized data that a simple text search might miss.

How to fix

The WP-CLI search-replace from Cause 1 handles both regular content URLs and those inside inline styles, including serialized data. Run the same command:

wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables

For CSS files in your theme, edit the files to use https:// or protocol-relative URLs. Better yet, use relative paths for resources on the same domain:

/* Bad */
background-image: url('http://example.com/wp-content/uploads/hero.jpg');

/* Good - relative path */
background-image: url('/wp-content/uploads/hero.jpg');

/* Also good - protocol-relative */
background-image: url('//example.com/wp-content/uploads/hero.jpg');

Cause 6: CDN serving assets over HTTP#

If your site uses a Content Delivery Network, the CDN must also serve content over HTTPS. A misconfigured CDN is a common source of mixed content because the CDN URL replaces your domain in asset URLs, and if the CDN connection is not set up for SSL, every asset it serves triggers a mixed content warning.

This affects CSS files, JavaScript files, images, and fonts – basically everything the CDN is configured to serve.

How to diagnose

Look at the failing URLs in the browser’s Network tab. If they point to a CDN domain (like cdn.yourdomain.com , yourdomain-cdn.example.com , or a generic CDN URL) and use http:// , the CDN configuration is the issue.

Common scenarios:

  • The CDN pull zone was created before SSL was set up and defaults to HTTP
  • The CDN has SSL enabled but the WordPress plugin generating CDN URLs is using  http://
  • The CDN’s SSL certificate has expired or is misconfigured (which may show as an ERR_SSL_PROTOCOL_ERROR rather than mixed content)

How to fix

In the CDN configuration:

Ensure the CDN pull zone is set to use HTTPS for both the origin connection (CDN to your server) and the edge connection (visitor to CDN). Most CDN providers offer free SSL on their edge servers. Enable it if it is not already active.

In the WordPress CDN plugin:

If you are using a plugin like WP Super Cache, W3 Total Cache, or a CDN-specific plugin, check the CDN URL setting. It should use https:// :

Correct:  https://cdn.yourdomain.com
Wrong:    http://cdn.yourdomain.com

For CDN custom domains:

If your CDN uses a custom subdomain like cdn.yourdomain.com , that subdomain needs its own SSL certificate or needs to be covered by a wildcard certificate. See How to install an SSL certificate if you need to set this up. If you are deciding between certificate types, Free vs paid SSL certificates: what is the actual difference covers the tradeoffs.

After fixing the CDN configuration, purge the CDN cache completely so that stale HTTP URLs are not served from edge nodes.

Using Really Simple SSL as a temporary fix#

The Really Simple SSL plugin is often recommended as a quick fix for mixed content. It works by intercepting WordPress output and rewriting HTTP URLs to HTTPS on the fly before the page is sent to the browser. It also sets the correct WordPress URL options and adds redirect rules.

It does work as a band-aid. If you enable it, most mixed content warnings will disappear immediately. But there are good reasons to treat it as temporary rather than permanent:

Performance cost. The plugin runs output buffering on every page load to find and replace URLs. That is extra processing on every request that a properly configured site does not need.

It masks the problem. The HTTP URLs are still in your database. If you ever deactivate the plugin, all the mixed content comes back. You are adding a dependency on a plugin to compensate for a configuration issue.

It cannot fix everything. External resources loaded over HTTP from third-party domains, hardcoded URLs in JavaScript files, and some dynamically generated URLs may not be caught by the output buffer.

The right approach: install Really Simple SSL to stop the warnings immediately, then fix the actual causes using the methods above (database search-replace, theme/plugin updates, CDN configuration), and then deactivate the plugin once the real URLs are corrected.

How Hostney handles this#

Hostney’s platform is designed so that mixed content problems are unlikely to occur in the first place, and straightforward to fix when they do.

SSL by default. Every site hosted on Hostney gets a free SSL certificate automatically. Sites are served over HTTPS from the moment they are created, which means content uploaded through WordPress uses HTTPS URLs from day one. The most common cause of mixed content – migrating an existing site from HTTP to HTTPS – does not apply to sites that were born on HTTPS.

Automatic HTTP-to-HTTPS redirect. All HTTP requests are redirected to HTTPS at the server level, before they reach WordPress. This means even if someone accesses an HTTP URL directly, they get redirected to the secure version. This does not fix mixed content on the page itself (the browser still sees the HTTP request before the redirect), but it ensures that no content is ever served over plain HTTP.

Built-in search and replace. The Hostney control panel includes a search and replace tool directly in the WordPress management interface. Go to Development > WordPress, select your site, click Manage, and open the Search & replace tab. Enter the old HTTP URL and the new HTTPS URL, and the platform runs a WP-CLI search-replace on the server. No SSH required, no plugin to install, and it handles serialized data correctly. If you prefer the command line, every account also includes SSH access with WP-CLI available.

Container isolation. Each site runs in its own container with its own PHP and web server configuration. If you need to add FORCE_SSL_ADMIN or the X-Forwarded-Proto detection to wp-config.php , you can do so without worrying about affecting other sites.

If you are migrating a site to Hostney from a host that did not use SSL, the main step is running the search and replace after the migration to update all URLs in the database. You can do this from the control panel’s Search & replace tab or via WP-CLI over SSH. The SSL certificate and server configuration are already in place.

Summary#

Mixed content errors mean your HTTPS page is loading some resources over HTTP. Browsers flag this as insecure, remove the padlock icon, and block active content (scripts and stylesheets) entirely. The fix depends on where the HTTP URLs are coming from.

The six causes, roughly in order of how often they occur: hardcoded HTTP URLs in the WordPress database (fix with WP-CLI search-replace), theme or plugin files with hardcoded HTTP URLs (fix by updating or editing the code), external resources loaded over HTTP (fix by updating the URLs to HTTPS), WordPress site URL settings still on HTTP (fix in settings or wp-config.php), CSS background images and inline styles with HTTP URLs (fix with the same database search-replace), and CDN misconfiguration (fix in the CDN settings).

Start by opening the browser developer tools and looking at the Console and Network tabs. Every mixed content error tells you the exact URL that is causing the problem. Once you know the URL, you can trace it back to the database, a theme file, a plugin, or a CDN setting.

For most sites, the combination of wp search-replace on the database, updating the site URL settings, and checking the theme and plugins resolves everything. The Really Simple SSL plugin is a valid quick fix but should not be your long-term solution. For a broader overview of WordPress errors and their fixes, see How to fix the most common WordPress errors.

Related articles