Guide WordPress

How to fix mixed content warnings in WordPress

Why a site on HTTPS still triggers a "not fully secure" warning, and how to hunt down and fix every http reference causing it.

Updated 8 min read Intermediate

A mixed content warning means the page itself loaded over HTTPS, but something on it — an image, a stylesheet, a script — loaded over plain http. Browsers still display the page, but they will not show it as fully secure, and in some cases will silently block the insecure resource entirely, which is usually how the problem first gets noticed: an image that simply is not there.

Find out what is actually insecure

Open the page in a browser, open its developer console, and reload. Every browser reports mixed content in the console, usually naming the exact URL that failed and which element requested it. This tells you precisely what to fix rather than leaving you to guess.

Check more than the home page

Mixed content is often specific to certain pages — a particular post with an old embedded image, or a page built before the migration to HTTPS. Check a sample of pages rather than assuming the home page tells you everything.

Step 1: confirm your WordPress addresses are set to https

In Settings → General, both the WordPress Address (URL) and Site Address (URL) fields must begin https://. If either still says http://, WordPress itself is generating insecure links throughout the site, and nothing else you do will fully fix the problem.

If you cannot log in to change this

A wrong site address can sometimes cause a redirect loop that stops you reaching wp-admin at all. If that happens, the same two values can be set directly in wp-config.php instead, which overrides the database:

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

Correcting the site address setting only affects links WordPress generates going forward — it does nothing for http:// URLs already saved inside old posts, pages, and widget content. Those need to be rewritten directly.

If you have WP-CLI access, this is the safe and fast way to do it:

wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --skip-columns=guid

Run it first with --dry-run added to see what would change without actually changing anything:

wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --dry-run
Why --skip-columns=guid matters

The GUID column is meant to be a permanent, unchanging identifier for each post, used by things like RSS readers to recognise content they have already seen. Rewriting it can cause external services to treat every post as newly published. Excluding it from the search and replace avoids that side effect while still fixing every visible link.

Without command-line access, a database search-and-replace plugin does the same job from wp-admin, or the change can be made directly in phpMyAdmin — see searching and replacing inside a database for the manual approach and its risks.

Step 3: check your theme and plugin settings

Search and replace fixes content stored in the database, but some sources of mixed content live outside it.

  • Theme customiser settings, such as a logo or background image uploaded with an absolute http:// URL saved in an option rather than referenced by ID.
  • Hardcoded links in theme files, where a developer typed a full http:// address directly into a template rather than letting WordPress generate it. These will not be caught by a database search and replace at all, because they are not in the database — check header.php, footer.php, and any file that loads external scripts or fonts.
  • Plugin settings stored as plain text options, particularly for embedded widgets, chat tools, or analytics scripts that were configured with a full URL when the site was still on http.

Step 4: force HTTPS as a safety net

Once the direct causes are fixed, adding a redirect from http to https at the server level catches anything you missed and stops the insecure version of the site from being reachable at all. This is usually a rule in .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

This redirects visitors, but it does not by itself stop the mixed content warning — a resource requested over http and then redirected to https still shows briefly as an insecure request in some browsers. Fixing the actual source, as above, is what removes the warning; the redirect is what stops anyone reaching the insecure version directly in the first place.

After you have fixed it

Clear any page caching plugin and your browser cache, then recheck the console on a handful of pages, including at least one older post likely to contain legacy links. Mixed content that reappears after a while is usually new content being added with an old, copied http link rather than the original problem returning — a quick habit of pasting fresh links rather than reusing old ones avoids it recurring.

Frequently asked questions

Why does this happen after I install an SSL certificate?

Because installing the certificate only makes HTTPS available — it does not rewrite the links already saved inside your posts, pages, theme settings and uploaded media, which were written when the site was still on http. Those old references keep pointing at the insecure version of each address until you update them.

Is a mixed content warning actually a security risk?

The insecure elements it flags can, in principle, be intercepted or altered in transit, even though the page around them is encrypted. In practice the risk is usually small for something like an image, but browsers do not distinguish based on how serious it is — they simply stop showing the padlock as fully secure, which looks bad to visitors regardless of the actual risk.

Related reading