You enabled SSL and forced HTTPS. The padlock should appear — but instead browsers show “Not secure” or a warning shield. Console shows messages about “mixed content” — your HTTPS page is loading resources over HTTP. This is one of the most common WordPress migration issues. Fixing it requires updating every hardcoded HTTP URL in posts, themes, settings, and plugin data.
What “mixed content” means
An HTTPS page that loads any resource (image, script, stylesheet, font, iframe) over HTTP is mixed content. The browser flags this because the HTTP resource could be tampered with in transit, undermining the security of the HTTPS connection.
Severity by resource type:
- Active content (scripts, iframes, CSS) — Blocked entirely by modern browsers. Page often broken visually.
- Passive content (images, audio, video) — Loaded but padlock removed, warning shown.
Either way, users see your site as “not fully secure” even though you spent the effort to install SSL.
Finding what’s still HTTP
Browser DevTools
- Open your site in Chrome / Firefox.
- F12 / right-click → Inspect.
- Console tab — shows “Mixed Content” warnings with the exact URL of each offending resource.
- Network tab — filter by “Status: failed” or look for any URL starting http://.
Note the URLs. They’re the targets to fix.
Online checker
Tools like whynopadlock.com or mixed-content-scan.glitch.me scan your entire site and report every mixed-content resource. Easier than checking page by page.
Common sources
Hardcoded image URLs in post content
Old posts with image URLs like http://yoursite.com/wp-content/uploads/image.jpg stored in the database. Most common cause.
WordPress Settings → Site URL / WordPress Address
If these still say http:// you have problems. Settings → General → both URLs should start with https://.
Theme hardcoded URLs
Theme files (header.php, footer.php) sometimes contain hardcoded http:// URLs for external assets. Less common in modern themes; older custom themes are likely suspects.
Plugin settings
Slider plugins, gallery plugins, and others store URLs in their own settings tables or option fields. Often these need plugin-specific updates.
Custom widgets and HTML blocks
Anywhere someone pasted raw HTML with http:// URLs — sidebar widgets, footer code, custom blocks.
External resources (the trickiest)
An old plugin embeds an external script via http:// CDN. Update the plugin or replace the embed with https://.
Fix method 1: Better Search Replace plugin
Easiest for non-developers. Plugin Better Search Replace (free, mature) does database-wide find-and-replace safely.
- Install Better Search Replace plugin.
- Plugins → Better Search Replace.
- Search for:
http://yourdomain.com - Replace with:
https://yourdomain.com - Select tables: select all (Ctrl+A on the list).
- Dry run first (checkbox enabled).
- Review output: tells you how many rows would be changed.
- If looks correct, uncheck Dry run and Run again.
This catches URLs in all post content, post meta, options, custom fields, etc. — usually 95% of the problem.
Fix method 2: WP-CLI
If you have SSH access:
# Dry run first
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --dry-run
# Then do it for real
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com'
WP-CLI handles serialized data automatically (unlike a raw SQL replace which would break serialized arrays).
Fix method 3: Add HTTPS-only meta tag
Site-wide directive that tells browsers to upgrade all HTTP requests to HTTPS automatically. Add to .htaccess or HTTP headers:
Header set Content-Security-Policy "upgrade-insecure-requests"
Or as a meta tag in your theme’s head.php:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
This is a band-aid — works for browsers that support it (most modern ones), doesn’t fix the underlying hardcoded HTTP URLs. Use to suppress warnings temporarily; clean URLs properly when time permits.
Forcing HTTPS at server level
After cleaning URLs, redirect HTTP visitors to HTTPS via .htaccess:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Anyone landing on http://yourdomain.com gets sent to https:// automatically.
Verifying after fixes
- Hard refresh (Ctrl+Shift+R) the page in browser.
- Check the padlock — should be solid, no warning.
- DevTools console — no mixed content warnings.
- Test the most important page types (home, single post, category, archive, contact form).
- Test on mobile too — sometimes desktop and mobile differ if responsive images use different URLs.
Cache might be hiding fixed pages. Purge LiteSpeed Cache, WP Super Cache, CDN cache, browser cache between testing.
For sites with custom URL structures
If you also moved domains (e.g. from www.old.com to www.new.com) you have two replace operations:
- http://www.old.com → https://www.new.com
- http://old.com → https://new.com (without www)
Run both passes; verify in DevTools after.
Common issues
“Search-replace shows 0 rows changed but I still see HTTP URLs.” URLs might be in a non-WordPress source — theme files, plugin code. Check those.
“After replace, my site is partially broken.” Roll back via backup; try WP-CLI version which handles serialized data better. Or restore from JetBackup.
“External resources like Google Fonts cause mixed content.” Update theme/plugin to use protocol-relative or https:// URLs for external resources. Sometimes manual code edit needed.
“Padlock works on one page but not another.” The broken page has specific resources still loading over HTTP. Per-page DevTools inspection finds them.
“After fixing mixed content, AutoSSL keeps overwriting my paid cert.” Different issue. SSL/TLS Status in cPanel — exclude domains from AutoSSL if you want to keep specific paid certs.
What’s next
- SSL setup itself: AutoSSL guide.
- Force HTTPS via .htaccess: .htaccess essentials.
- WordPress security beyond HTTPS: WordPress hardening.
Mixed content is annoying but mechanical to fix. Better Search Replace plugin solves 95% of cases in ten minutes. The remaining edge cases — theme code, external resources — require per-source attention. Confirm with DevTools that the warnings clear, then enforce HTTPS redirects.
Was this helpful?
Thanks for your feedback!