The padlock that disappears on certain pages
You migrated your WordPress site from HTTP to HTTPS. The homepage loads with a padlock. Your login page shows the padlock. But then you open a blog post you published two years ago and the padlock is gone. The browser address bar says "Not Secure." You check another page — same thing. Some pages are secure, some are not.
Your visitors see it too. They land on a page, see the "Not Secure" warning, and leave. If you run a WooCommerce store, customers see the warning on product pages or at checkout and abandon their cart. They do not investigate why the warning appears. They do not check whether the payment form is actually secure. They see "Not Secure" and they go to a competitor.
The SSL certificate is not the problem. The certificate is valid, installed correctly, and working. The problem is mixed content — your page loads over HTTPS but some resources on the page are still loading over HTTP. One insecure image, one HTTP script, one unencrypted stylesheet is enough to strip the padlock from the address bar.
And here is the part that makes mixed content particularly dangerous: you cannot see it by glancing at your site. The page looks normal. The images load. The layout is fine. Everything appears to work. But the browser knows that some resources came over an unencrypted connection, and it warns your visitors accordingly.
What causes mixed content on WordPress sites
Mixed content is not a single problem — it is usually five or six problems layered on top of each other. Each one has a different source and requires a different fix. Missing any one of them means the "Not Secure" warning persists.
1. Hardcoded HTTP URLs in the WordPress database
This is the most common cause and the hardest to find manually. Every time you inserted an image into a post, added a link, configured a widget, or saved a page with the visual editor, WordPress stored the full URL in the database. If your site was running on HTTP at the time, every one of those URLs starts with http://.
Installing an SSL certificate does not update the database. Your posts, pages, custom fields, widget settings, theme options, and plugin configurations all still contain http://yourdomain.com URLs. Every image in every old blog post loads over HTTP. Every internal link points to the HTTP version. Every embedded video, every PDF link, every custom field with a URL — all HTTP.
On a site with hundreds of posts, there can be thousands of hardcoded HTTP URLs scattered across dozens of database tables. You cannot fix them one by one from the WordPress editor. You need a database-wide search and replace.
2. Plugin assets loading over HTTP
WordPress plugins enqueue their JavaScript and CSS files using wp_enqueue_script() and wp_enqueue_style(). Well-written plugins use protocol-relative URLs or WordPress functions that automatically use the correct protocol. Poorly written plugins hardcode http:// in their asset URLs.
When a plugin loads its stylesheet from http://yourdomain.com/wp-content/plugins/some-plugin/style.css, browsers classify this as active mixed content and block it entirely. The stylesheet does not load. The plugin's visual elements break. And the "Not Secure" warning appears.
This is particularly common with older plugins, free plugins with infrequent updates, and premium plugins purchased from third-party marketplaces outside the official WordPress repository. The plugin works perfectly on HTTP — you only discover the mixed content issue after migrating to HTTPS.
3. CDN still serving assets over HTTP
If you use a CDN — Cloudflare, StackPath, KeyCDN, BunnyCDN, or any other — the CDN has its own SSL configuration. Installing SSL on your origin server does not automatically configure SSL on the CDN. If your CDN is set up to pull assets from your origin over HTTP, or if the CDN URLs in your WordPress configuration use http://, every asset served through the CDN triggers a mixed content warning.
CDN plugins like CDN Enabler or W3 Total Cache store the CDN URL in their settings. If you configured the CDN before migrating to HTTPS, the stored URL is http://cdn.yourdomain.com. Every image, script, and stylesheet rewritten by the CDN plugin points to the HTTP version of the CDN.
4. Images with absolute HTTP paths in post content
WordPress stores image URLs as absolute paths in the wp_posts table. When you insert an image into a post, the HTML stored in the database looks like: <img src="http://yourdomain.com/wp-content/uploads/2024/03/photo.jpg">. That http:// prefix stays in the database forever unless you explicitly change it.
This affects every image inserted before the HTTPS migration — featured images, inline images in post content, gallery images, images in page builder elements, and background images set through custom fields. On a site that has been publishing content for years, there can be thousands of these references.
5. Theme hardcoding HTTP resources
Some WordPress themes hardcode URLs for fonts, icon libraries, or external resources directly in their template files or theme options. A theme that loads Google Fonts via http://fonts.googleapis.com instead of https:// or a protocol-relative URL causes mixed content on every page that uses the font.
Custom themes built by agencies or freelancers are especially prone to this. The developer built the theme when the site was on HTTP and hardcoded URLs throughout. Logo images, background images, and external script includes can all contain HTTP paths buried in theme files or stored in theme option values in the database.
6. External embeds and iframes using HTTP
Embedded content from third-party services — YouTube videos, Google Maps, social media widgets, advertising scripts, analytics pixels — can trigger mixed content if the embed code uses HTTP. Older embed codes copied from third-party services years ago may use http:// even though the service now supports HTTPS.
This is common in posts that embed content from smaller services or legacy platforms that were slower to adopt HTTPS. The embed works and displays correctly, but the HTTP iframe or script triggers the mixed content warning.
How to find every mixed content source on your site
Method 1: Browser developer console
Open your site in Chrome, press F12to open Developer Tools, and click the Console tab. Mixed content warnings appear as yellow warnings with the prefix "Mixed Content." Each warning shows the specific URL that is loading over HTTP. Check multiple pages — mixed content can vary from page to page depending on which images and resources each page loads.
The limitation of this method is that you have to manually visit every page. On a site with hundreds of pages, this is impractical. You will find the mixed content on the pages you check and miss it on the pages you do not.
Method 2: Search your database for HTTP URLs
Connect to your WordPress database using phpMyAdmin, Adminer, or the command line. Run this query:
SELECT * FROM wp_posts WHERE post_content LIKE '%http://yourdomain.com%';
Replace yourdomain.com with your actual domain and wp_ with your table prefix. This shows every post and page that contains a hardcoded HTTP URL. Check wp_options, wp_postmeta, and wp_termmeta tables as well — plugins and themes store URLs throughout the database.
Method 3: Use the Better Search Replace plugin
Install the Better Search Replace plugin from the WordPress repository. In the plugin settings:
- Set "Search for" to
http://yourdomain.com - Set "Replace with" to
https://yourdomain.com - Select all database tables
- Check "Run as dry run" first to see what will change
- Review the results — make sure the count looks reasonable
- Uncheck "Run as dry run" and run the replacement
This handles the database-wide replacement in one operation. It correctly handles serialised data in WordPress options and postmeta tables, which a simple SQL REPLACE command would corrupt.
How to fix each mixed content source
Fix 1: Database search and replace for hardcoded URLs
Use Better Search Replace or WP-CLI to replace all instances of http://yourdomain.com with https://yourdomain.com across all database tables. If you also have http://www.yourdomain.com references, run a second replacement for that variant. Always back up your database before running the replacement.
With WP-CLI, the command is: wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables
Fix 2: Update plugin and theme settings
After the database replacement, check each plugin's settings page. Some plugins store URLs in their own settings format that the search and replace might not catch. CDN plugins, caching plugins, and SEO plugins often have URL fields that need manual updating. Check your theme's customiser settings, logo upload, and any custom URL fields.
Fix 3: Update your CDN configuration
Log into your CDN provider's dashboard and verify that the origin URL uses HTTPS. Update any CDN URLs stored in WordPress plugins or theme settings to use https://. If you use Cloudflare, set the SSL mode to "Full (strict)" and enable "Always Use HTTPS" — but be aware that the latter can cause issues with Let's Encrypt renewal as described in our SSL certificate expiry guide.
Fix 4: Force HTTPS redirects at the server level
Add an HTTP to HTTPS redirect in your .htaccess file or server configuration. This ensures that any remaining HTTP URLs in your content automatically redirect to HTTPS. While this does not fix the mixed content warning itself — the browser flags the initial HTTP request before the redirect — it prevents any insecure content from actually loading over HTTP.
For Apache, add to your .htaccess:
RewriteEngine OnRewriteCond %{HTTPS} offRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Fix 5: Update WordPress and Site URL settings
In WordPress admin, go to Settings > General. Make sure both "WordPress Address (URL)" and "Site Address (URL)" use https://. If these are still set to HTTP, WordPress generates HTTP URLs for all internal links, asset paths, and canonical URLs. This single setting affects hundreds of URLs across your site.
Fix 6: Check and update external embeds
Search your post content for http:// references to external services. Update YouTube embeds, Google Maps iframes, social media widgets, and any other third-party embeds to use https://. Most major services have supported HTTPS for years — changing the protocol in the embed code is usually all that is needed.
The Mozilla Developer Network mixed content documentation provides a comprehensive reference on how browsers handle different types of mixed content and which resources are blocked versus warned.
How to detect mixed content automatically with Uptrue
Fixing mixed content once is relatively straightforward. The real challenge is keeping it fixed. A plugin update can reintroduce HTTP asset URLs. A content editor can paste an HTTP image link into a post. A CDN configuration change can revert to HTTP. A theme update can reset a hardcoded URL.
Uptrue's monitoring catches these regressions automatically, so you do not discover them from a customer complaint or a Google ranking drop.
Step 1: Set up an SSL monitor for your domain
- Sign up at uptrue.io/signup (free plan available)
- Click Add Monitor from your dashboard
- Select SSL Certificate as the monitor type
- Enter your domain name
- Set the check interval to every hour
- Configure alert channels — Slack, email, or Microsoft Teams
The SSL monitor validates your certificate configuration and detects issues that contribute to mixed content warnings — certificate chain problems, protocol mismatches, and configuration errors that cause browsers to flag your site as insecure.
Step 2: Add keyword monitors for critical pages
- Click Add Monitor again
- Select Keyword as the monitor type
- Enter the URL of a critical page — homepage, checkout, contact
- Set the keyword to a phrase that always appears when the page loads correctly — your site title, a heading, or a product name
- Set the check type to "Page must contain"
- Set the interval to 1 minute
When active mixed content is blocked by the browser, page elements that depend on those scripts or stylesheets break. If a critical script is blocked, interactive elements stop working and the page may render differently. The keyword monitor detects when the expected content is missing — catching the downstream effects of mixed content blocking.
Step 3: Monitor your WooCommerce checkout
If you run WooCommerce, the checkout page is the most sensitive to mixed content. A single insecure resource can trigger the "Not Secure" warning on the page where customers enter their payment details. Set up a separate HTTP monitor for your checkout URL with a 1-minute interval. Any SSL or mixed content issue that affects checkout needs to be caught immediately.
Step 4: Set up alerts that reach you before customers complain
- Slack — immediate notification in your ops channel
- Microsoft Teams — for teams using Microsoft tools
- Email — as a backup alert trail
- Webhook — to integrate with PagerDuty, Opsgenie, or your incident management system
Check your site for SSL issues right now
Instant scan showing your certificate status, chain validation, and configuration issues. Free, no signup required.
Free SSL CheckerPreventing mixed content from coming back
Mixed content is not a one-time fix. It is an ongoing risk that can be reintroduced by any content change, plugin update, or configuration modification. These practices reduce the chances of recurrence.
Use relative URLs or protocol-relative URLs where possible
When adding links or images manually, use relative URLs (/wp-content/uploads/image.jpg) instead of absolute URLs. This avoids the HTTP vs HTTPS problem entirely because the browser automatically uses the protocol of the current page.
Set the Content-Security-Policy header
The Content-Security-Policy: upgrade-insecure-requests header tells browsers to automatically upgrade HTTP resource requests to HTTPS. This acts as a safety net — if an HTTP URL slips through, the browser upgrades it to HTTPS before making the request. Add this header in your web server configuration or via a WordPress security plugin.
Audit after every plugin and theme update
Plugin and theme updates can reintroduce hardcoded HTTP URLs in their settings or asset files. After updating any plugin or theme, check the browser console on a few key pages for new mixed content warnings. Better yet, rely on Uptrue's monitoring to alert you automatically if an update reintroduces insecure resources.
Train content editors to use HTTPS URLs
If you have multiple people editing content on your WordPress site, make sure they understand that all URLs pasted into posts must use https://. This includes image URLs from external sources, embed codes, and links to documents. One HTTP URL in one post is enough to strip the padlock from that page.
The WordPress documentation on HTTPS provides additional context on configuring WordPress for secure connections and avoiding common HTTPS issues.
Stop losing trust over insecure resources you cannot see
Mixed content is invisible to you when you are browsing your own site. Your browser might have cached the secure version. You might be checking the homepage while the problem is on a product page. You might have fixed the database URLs but missed a plugin setting. The "Not Secure" warning only appears for some visitors on some pages — and they leave without telling you.
Uptrue monitors your SSL configuration continuously and checks your critical pages every minute. When a plugin update, content change, or CDN misconfiguration reintroduces mixed content, you get alerted before your visitors see the warning. You fix it in minutes instead of losing traffic for days.
Set up SSL and keyword monitoring now. The next plugin update could reintroduce the problem you already fixed.
Catch mixed content before your visitors do
Free plan available. SSL monitoring, keyword monitoring, and AI-powered reports. No credit card required.
Frequently asked questions
What is mixed content on a WordPress site?
Mixed content occurs when a page loaded over HTTPS includes resources — images, scripts, stylesheets, iframes, or fonts — that are loaded over HTTP. The page itself is encrypted, but the insecure resources create a security gap. Browsers flag this as "Not Secure" because an attacker could intercept or modify the HTTP resources in transit, even though the page itself was loaded securely. There are two types: active mixed content (scripts, iframes, stylesheets) which browsers block entirely, and passive mixed content (images, audio, video) which browsers may load but flag with a warning.
Why does my WordPress site show "Not Secure" after installing SSL?
Installing an SSL certificate only encrypts the connection between the browser and your server. It does not automatically update the URLs of every resource your site loads. If your WordPress database contains hardcoded http:// URLs in post content, widget text, theme options, or plugin settings, those resources will still load over HTTP. Similarly, plugins that enqueue scripts or stylesheets using http:// URLs, CDN configurations that have not been updated to HTTPS, and images inserted with absolute HTTP paths all cause mixed content warnings even though your SSL certificate is valid and active.
Does mixed content affect SEO?
Yes. Google has used HTTPS as a ranking signal since 2014 and Chrome marks pages with mixed content as "Not Secure" in the address bar. Pages that trigger mixed content warnings may receive lower trust signals from Google. Active mixed content that browsers block can also break page functionality — missing scripts can prevent forms, navigation, and interactive elements from working. If Google crawls a page where critical scripts are blocked due to mixed content, the page may be indexed without important content, affecting both rankings and how the page appears in search results.
Can Uptrue detect mixed content errors on my WordPress site?
Yes. Uptrue offers two monitoring approaches that catch mixed content issues. The SSL monitor validates your certificate and detects configuration problems that contribute to mixed content warnings. The keyword monitor can check your pages for the presence of "not secure" indicators or verify that specific secure elements are loading correctly. Combined, these monitors alert you within 60 seconds if a plugin update, content change, or CDN misconfiguration reintroduces mixed content on any monitored page.