Skip to main content Skip to content
furyhost
Get started

Fix Mixed Content Warnings on WordPress

Mixed content warning on a WordPress site served over HTTPS

Updated for WordPress 7.1 and PHP 8.3 — 8 September 2026.

A mixed content warning on WordPress means your page loaded over HTTPS but asked for something over plain HTTP, and the browser is telling you it either blocked that request or is about to. The certificate is not the problem — if it were, the page would not load at all. What you are fixing is a set of hardcoded http:// URLs left behind in your database and your theme, usually after a migration or an HTTPS switchover.

Understand what the browser is actually complaining about

Browsers treat two kinds of mixed content very differently, and knowing which you have tells you how urgent it is. MDN’s mixed content reference sets out the distinction.

  • Active mixed content — scripts, stylesheets, iframes and fonts. These can rewrite the whole page, so browsers block them outright. This is what breaks layouts and stops functionality working.
  • Passive mixed content — images, audio and video. Historically loaded with a warning; modern browsers increasingly upgrade or block these too.

So a site that looks broken after moving to HTTPS is usually not broken at all — its CSS and JavaScript are simply being blocked. That is why the fix so often produces an instant, dramatic improvement.

Find every offending URL before changing anything

Your browser’s console names the exact resources, which turns a vague warning into a specific list. Open developer tools, reload the page, and read the console: each mixed content message names the URL that was blocked or flagged. The Network tab shows the same requests with their full paths.

Check more than the homepage. Mixed content hides in places that are not on your main template — old blog posts with pasted images, sidebar widgets, page-builder modules, and theme options such as a logo or background image stored with an absolute URL. Test a post, an archive, a page built in your builder, and any form or checkout page.

Set the site URLs first

If WordPress still thinks it lives at an http:// address, everything it generates will point there. Check Settings → General and confirm both WordPress Address and Site Address use https://. Over WP-CLI:

wp option get siteurl
wp option get home
wp option update siteurl 'https://example.com'
wp option update home 'https://example.com'

If those values are defined as constants in wp-config.php, the database is ignored and the options screen will be greyed out — edit the constants instead. WordPress documents the whole switchover in changing a site to HTTPS, and the constants themselves in the wp-config.php reference.

Rewrite the URLs stored in your database

Old content holds absolute http:// URLs in post content, options and metadata, and only a search and replace will clear them. Do not do this with a plain SQL query. WordPress stores widget settings, theme options and builder layouts as serialized PHP, where strings carry their own length — a naive find-and-replace corrupts them, and the damage often does not surface until weeks later.

WP-CLI handles serialized data correctly. Take a database backup first, then preview:

wp db export backup-before-https.sql
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run

Read the report. If the counts look sane, run it for real:

wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guid

Two details that matter. --skip-columns=guid is deliberate: the GUID column is a permanent identifier for feed readers, not a link, and rewriting it makes subscribers see every old post as new. And the WP-CLI search-replace documentation confirms it handles serialized data intelligently and does not change primary keys — which is exactly why it is the right tool and a SQL query is not.

Replace only your own domain. Rewriting third-party URLs to HTTPS when that host does not support it breaks them completely.

Check the theme and plugin code you control

Hardcoded URLs in template files survive any database replacement, because they were never in the database. Search your child theme and any custom plugin for http:// and replace those with protocol-relative references or, better, the appropriate WordPress function so the URL follows the site setting rather than being fixed in code.

This is also where enqueued assets go wrong — a script or stylesheet registered via wp_enqueue_style() with an absolute HTTP URL is active mixed content, so it gets blocked, and the visible symptom is a broken layout rather than a padlock warning. Because this is theme code, changes belong in a child theme rather than a parent that an update will overwrite.

Purge caches before you decide it did not work

Cached HTML generated before the fix still contains the old URLs, so the warning persists even though the underlying content is now correct. Clear your CDN, host cache, caching plugin and any page-builder CSS, then retest in a private window.

This is the single most common reason people conclude the search and replace failed when it worked perfectly. If you are not sure which layer is holding the old copy, the process for finding a stale cache applies exactly as written.

Avoid the plugin-as-permanent-fix trap

Plugins that rewrite HTTP URLs on the fly are useful for getting a padlock back today, and I would rather you used one than left a store insecure over a weekend. But be honest about what it is: the wrong URLs are still in your database, and every page load now costs a filter pass to paper over them.

Fix the data properly, then remove the plugin. If you deactivate it later and the warnings return, that is not an argument for keeping it — it is confirmation the underlying problem was never fixed.

Frequently asked questions

Why does my padlock show a warning when my SSL certificate is valid?

Because the certificate and the page contents are separate things. The certificate secures the connection; the warning says the page requested at least one resource over plain HTTP. Both can be true at once.

Can I use a SQL query instead of WP-CLI?

Not safely. Serialized PHP data stores string lengths alongside the strings, and a plain SQL replacement leaves those lengths wrong, corrupting widget settings, theme options and builder layouts. WP-CLI handles serialization correctly.

Should I skip the GUID column?

Yes. GUIDs identify posts to feed readers rather than linking to them. Changing them can make every existing post appear as new to subscribers.

What about URLs pointing at other people’s sites?

Leave them unless you have checked that the destination supports HTTPS. Forcing a rewrite to a host that does not support it breaks the resource entirely. Replace only your own domain.

I fixed everything and the warning is still there. Why?

Almost always a cached page generated before the fix. Purge every caching layer and retest in a private window before looking for more URLs.

Related reading

Most mixed content arrives with a migration: the site moves, the domain changes, and thousands of absolute URLs come along unchanged. FuryHost runs the search and replace as part of migrating a site and checks the result page by page before anything points at the new server, so this is one of the problems you never meet. See what a migration involves.
Built with Oxygen