How to fix mixed content warnings in WordPress
Mixed content means a page loaded over https asks for an image, a stylesheet or a script over plain http. Browsers block those requests or change them, so parts of the page go missing. The fix is to find where the http addresses come from and correct them there.
- By
- WP Ministry
- Published
- Tested on
- WordPress 7.1.3, PHP 8.3.35
In short
- Mixed content means an https page asked for a file over http. Browsers block the request or change it.
- Your content is not damaged. The addresses are out of date, not the files.
- Check the two addresses under Settings, then General first. Then replace the old addresses stored in the database.
- If a CDN or proxy sits in front of the site, WordPress may not know that visitors are on https.
Mixed content means a page that was loaded over https asks for something else, such as an image, a stylesheet or a script, over plain http. Browsers do not let that pass. They change requests for images, audio and video to https by themselves, and they block the rest, stylesheets and scripts included. An image that is not there at its https address does not appear. A page whose stylesheet was blocked arrives without its styling.
Your content is not damaged. The files are where they were. What is out of date is the address the page uses to ask for them.
Find out where the http addresses come from
Open a page that has the problem. In Chrome, Edge or Firefox, right-click the page, choose Inspect, open the Console tab and reload. Each line about mixed content names the http address the page asked for.
- An address on your own domain that points into
/wp-includes/, or at a stylesheet or script inside/wp-content/: WordPress itself is writing http. Use the first fix, and the third if a CDN or proxy sits in front of the site. - An address on your own domain that points into
/wp-content/uploads/: it is stored in your content. Use the second fix. - An address on another site, or anything left over: use the last fix.
Where it goes wrong
A page request passes through each of these in turn. This one comes from the secure connection (HTTPS).
- Browser
- DNS
- HTTPS (this error comes from here)
- CDN or firewall
- Web server
- PHP
- WordPress
- Database and files
What causes it
The site's own address settings still begin with http
CommonWordPress builds the addresses of its own stylesheets, scripts and links from two settings. If they still say http, so can the pages.
Old http addresses are stored in the content
CommonAn image placed in a post is saved with its full address. Content written while the site was on http still holds http addresses, whatever the settings say now.
A CDN or proxy hides the visitor's https from WordPress
SometimesThe visitor's https connection ends at the proxy, which asks your server for the page over plain http. WordPress sees an http request and writes http addresses.
An http address is written into the theme, a setting or an embed
SometimesA theme file, a box you pasted code into, or an embed from another site names an http address that nothing in WordPress rewrites.
Fix: Correct addresses written into the theme, a setting or an embed
How to fix it
Set the site's two addresses to https
- Easy
- Low risk
- About 5 minutes
Step 1: Go to Settings, then General
The two addresses are near the top of the page.
Step 2: Check "WordPress Address (URL)" and "Site Address (URL)"
Both should begin with
https://. If either begins withhttp://, change those letters and nothing else in the address.Step 3: Press Save Changes
WordPress logs you out. Log in again at the https address.
If the two boxes are greyed out, the addresses are set in wp-config.php, on the lines that define WP_HOME and WP_SITEURL. Change http:// to https:// there.
With WP-CLI, using your own domain in place of example.com:
wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'If the site then redirects in a loop, a proxy in front of it is hiding https from WordPress. Do the third fix. If it is only the login page that keeps coming back, see the login page refreshing and redirecting.
To undo it: Change the two addresses back to http.
Replace the http addresses stored in the database
- Takes care
- Back up first
- About 20 minutes
- Steps tested on WordPress 7.1.3
WP-CLI's search-replace command rewrites every stored copy of the old address in one pass.
Step 1: Do a dry run
Use your own domain in place of example.com, here and in the next step.
It lists each table and column that holds the old address, and ends with a line such as "Success: 2 replacements to be made." Nothing has been changed yet.
bashwp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid --report-changed-only --dry-runStep 2: Run it for real
This is the same command without
--dry-run.bashwp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid --report-changed-onlyStep 3: Repeat it for the other form of your domain
If the site has also been reached with
www.in front of the domain, or without it, run both commands again for that address.Step 4: Clear the cache and reload
If the site uses a page cache, clear it, then reload the page with the Console open.
What the command does, and what it leaves alone:
- It searches the tables WordPress itself registers. A plugin that keeps tables of its own may hold addresses too. Add
--all-tables-with-prefixto include them. - It understands the serialized format that themes and plugins store their settings in, and keeps it valid. A plain find-and-replace in a database tool does not, and can corrupt those settings.
--skip-columns=guidleaves each post's permanent identifier as it is. Feed readers use it to tell which posts they have already shown.- It changes the two address settings from the first fix as well, if they still said http.
- It does not touch files. An address written into a theme file is for the last fix.
No WP-CLI? Use a search-and-replace plugin. Choose one that says it handles serialized data and offers a dry run, and take the same backup first.
To undo it: Restore the database backup you took before you began.
Tell WordPress the visitor is on https
- Takes care
- Back up first
- About 10 minutes
- Steps tested on WordPress 7.1.3
This applies when a CDN, a load balancer or another proxy sits in front of your site and connects to your server over plain http. WordPress then writes http addresses for its own stylesheets and scripts, and the visitor's browser blocks them.
A proxy usually says what the visitor used in a header named X-Forwarded-Proto. These lines make WordPress take notice of it.
Step 1: Open wp-config.php
It is in the site's main folder, beside the
wp-contentfolder.Step 2: Add these lines above "That's all, stop editing"
wp-config.phpif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https' ) !== false ) { $_SERVER['HTTPS'] = 'on'; }Step 3: Save the file and reload the site over https
WordPress's own stylesheets and scripts now have https addresses. If nothing has changed, your proxy does not send that header. Ask its support which header says that the visitor used https.
Step 4: Set the two addresses to https
Do the first fix now, if the addresses still begin with
http://.
If your proxy can be set to connect to your server over https as well, that is the better arrangement. WordPress then sees https for itself, and these lines are not needed.
To undo it: Remove the three lines from wp-config.php.
Correct addresses written into the theme, a setting or an embed
- Takes care
- Low risk
- About 30 minutes
Step 1: List what is left
Reload the page with the Console open, as described above. Work through the addresses it still names.
Step 2: An address on your own domain
It is written into a theme file, or saved somewhere the replace did not reach. Look through the theme's options, your widgets and any box where you pasted code, such as a tracking snippet. Change
http://tohttps://. If it is in a theme file, ask the theme's developer for an update, or make the change in a child theme so that an update does not undo it.Step 3: An address on another site
Open the address in your browser with
https://in place ofhttp://. If the file loads, use the https address wherever you pasted the original. If it does not, that service does not offer the file over https: host a copy yourself if you are allowed to, or take it out.
When to get help
If the Console still lists http addresses after all four fixes, they are written by code at the moment the page is built, such as a plugin or the layouts a page builder has stored. Tracing each one back to its source takes someone who can read the theme's and the plugins' code.
Common questions
Is mixed content dangerous?
It can be. Anything sent over http can be read or changed on its way to the visitor, which is why browsers refuse to run a script that arrives that way. On a page that takes a login or a payment, fix it before anything else.
Why did some images disappear when the site moved to https?
The browser now asks for each image over https, even where the page says http. An image that lives on a server with no https, or behind a certificate that does not match, cannot be fetched that way and is left out.
Can a plugin fix this for me?
Some plugins rewrite http addresses to https each time a page is built. That clears the warning while the plugin is active, and nothing stored is changed. It is a fair stopgap. Replacing the stored addresses is the lasting fix.
I replaced everything and the warning is still there. Why?
You are probably looking at a saved copy. Clear the site's page cache, the CDN's cache if you use one, and your browser's. Then look at the Console again: what it still lists is real, and belongs to the last fix.
- GuideLocked out of WordPress admin: find which lockout you have and get back in
- GuideSlow WordPress admin: how to find the cause and fix it
- ResourceWooCommerce checkout is down: a runbook
- GuideWordPress site not showing up on Google: what to check, in order
- Guideadmin-ajax.php high CPU usage in WordPress: how to find what is calling it
- GuideHow to change WordPress permalinks without breaking your old links

