Browser Says “Not Secure” Even Though You Have SSL? Here's Why.
Your SSL certificate is valid, but the padlock in the address bar is broken, greyed out, or missing entirely, and the browser calls the page “Not Secure.” That's mixed content: the page itself is still loading some resources — an image, a script, a stylesheet — over plain, unencrypted http instead of https. The certificate isn't the problem; specific hardcoded links on the page are.
What is the problem?
“Mixed content” means a page loaded securely over https is also trying to load one or more individual resources — an image, a stylesheet, a script, a font — over plain, unencrypted http. Browsers treat that as a security downgrade: even though the page itself and its certificate are fine, an attacker on the network could theoretically tamper with that one unencrypted resource, so the browser shows a broken or missing padlock and often an explicit “Not Secure” label instead of the green-lock confidence you'd expect from a working SSL setup.
Quick answer: open your browser's DevTools console (F12) on the affected page. Mixed-content warnings are listed there explicitly, by resource URL, telling you exactly which http:// link needs to become https:// — no guessing required.
This is not a certificate problem, which is the most common misunderstanding. Renewing, reinstalling or upgrading the SSL certificate does nothing here, because the certificate itself was never at fault. The fix is changing the specific hardcoded http:// references on the page, not touching the certificate at all.
Common symptoms
- The address bar shows a broken, crossed-out, or missing padlock instead of a solid lock icon
- Chrome, Firefox or Edge explicitly labels the page “Not Secure” despite a valid, unexpired SSL certificate
- The browser console lists one or more “Mixed Content” warnings naming specific http:// URLs that were blocked or loaded insecurely
- Some images, background images, or embedded content simply fail to display, particularly in stricter browsers that block insecure resources outright rather than just warning about them
- It appeared right after migrating domains, restoring from an old backup, or moving from http to https for the first time
- Only some pages show the warning while others don't, usually tracking which pages contain older content or specific widgets
Why does this happen?
WordPress stores full URLs, including the protocol, directly inside post content, widget settings, theme customizer options, and sometimes serialized data in the database. When a site moves from http to https — whether through a fresh SSL install, a domain change, or restoring an old backup onto a site that already has SSL — anything that was hardcoded as http://yoursite.com/... stays exactly that way unless something explicitly rewrites it. The site-wide URL in Settings → General updates easily; individual hardcoded links inside content do not update on their own.
Modern browsers are strict about this specifically because mixed content defeats part of the point of https — an unencrypted image request can be intercepted and swapped, and a mixed unencrypted script is an even bigger risk, since browsers block those outright by default rather than merely warning.
Common technical causes
- Hardcoded http:// image or link URLs inside post and page content, often from content written or imported before SSL was enabled
- Theme customizer settings or widget fields (a logo URL, a custom CSS background-image, a header script) saved with the old protocol
- A theme or page-builder template imported from a demo that references the demo site's own http:// assets directly
- Third-party embeds and scripts (an old analytics snippet, a font CDN link, a social-share widget) still pointing at an http:// version of the resource
- A restored backup taken before SSL was enabled, reintroducing old http:// references sitewide on restore
- A recent domain migration where the redirect map handles page URLs but not asset URLs referenced inside content
How to diagnose it
- Open DevTools' Console tab (F12) on the affected page and reload. Every mixed-content resource is listed individually with its exact URL — this is the fastest, most precise diagnostic available.
- Run the free Website Health Checker for a broader pass across security headers and HTTPS status alongside other technical checks.
- Check whether the warning is sitewide or page-specific. If it's isolated to a handful of older posts, the cause is very likely content-level, not a site-wide setting.
- Search the database for hardcoded http:// references using your host's phpMyAdmin search or a plugin like Better Search Replace, scoped first to a dry run so you can review matches before changing anything.
- Check Settings → General in wp-admin to confirm the WordPress Address and Site Address are both set to https — if either still says http, that's a separate, more fundamental setting to fix first.
How to fix it, step by step
- Confirm Settings → General uses https for both URL fields before anything else — this is the site-wide baseline everything else depends on.
- Take a full backup before running any database search-and-replace — this step touches content directly and should always be reversible.
- Run a proper serialized-data-aware search-and-replace (via WP-CLI's
wp search-replace, or a plugin like Better Search Replace) changinghttp://yoursite.comtohttps://yoursite.comsitewide — a plain find-and-replace in phpMyAdmin can corrupt serialized widget and theme data, so use a tool built for WordPress's data format specifically. - Re-check the theme customizer and any widgets manually for hardcoded http:// image or script URLs the database pass might not catch, particularly in custom CSS fields.
- Update any third-party embed codes (fonts, analytics, social widgets) to their https:// versions directly in the source snippet.
- As a fast interim fix while the underlying data gets cleaned up, a plugin like SSL Insecure Content Fixer can rewrite insecure references on output — useful as a stopgap, not a substitute for fixing the stored data.
- Clear all caching layers (page cache, CDN, browser cache) and re-check the console on a hard refresh to confirm the warnings are actually gone, not just cached away.
When this needs professional help
Checking the console and swapping an obvious http:// link in a widget is realistic to do yourself. It's worth bringing in a developer when:
- The warnings are spread across hundreds of old posts and a careful, serialized-data-safe database replace is needed rather than manual edits
- You're not confident running a search-and-replace against production data without a tested backup and rollback plan
- The mixed content followed a domain migration and needs to be handled alongside the redirect map, not as a separate afterthought
- The site also runs an interim rewriting plugin and you want the underlying data actually cleaned up, not just patched on output indefinitely
How I can help
Mixed content almost always shows up after a migration, redesign, or SSL setup I'm already handling for a client, so I treat it as a standard part of that work rather than a separate fix. I run a serialized-data-safe search-and-replace, manually check theme and widget settings the automated pass can miss, and confirm the padlock is genuinely clean afterward — not just visually cleared by a cache.