How to Fix the Mixed Content Warning?

You installed an SSL certificate on your site, but the lock in the address bar still doesn't appear, or it says "not secure" with an exclamation mark. The most common reason for this is mixed content: while the page itself loads over HTTPS, some of its resources are still being called over HTTP. In this article, we explain how to find and permanently fix the problem.

What is mixed content?

When a secure (https://) page loads an insecure (http://) resource, the browser treats it as a security vulnerability. There are two types:

  • Passive mixed content: Resources such as images, video, and audio. The browser usually loads them but removes the lock and writes a warning to the console.
  • Active mixed content: Scripts, style files (CSS), iframes, XHR/fetch calls. Because these could hijack the page, they are blocked by the browser and your page looks broken.

Step 1 — Find the culprit resources

Open your browser's developer tools (F12) and look at the Console tab. Mixed content warnings are clearly listed:

Mixed Content: The page at 'https://yourdomain.com/' was loaded over HTTPS,
but requested an insecure resource 'http://yourdomain.com/img/logo.png'.
This content should also be served over HTTPS.

Each line tells you which resource was loaded over HTTP. Make a list of these to determine the addresses you need to fix.

Image: <Mixed content warnings in the DevTools Console>
The developer tools console lists the insecure resources one by one.

Step 2 — Fix the resource addresses

The most permanent fix is to change the http:// prefixes in the page's resources to https://. If possible, use protocol-relative or root-relative paths that don't include the domain:

<!-- Wrong -->
<img src="http://yourdomain.com/img/logo.png">
<script src="http://cdn.example.com/lib.js"></script>

<!-- Correct -->
<img src="https://yourdomain.com/img/logo.png">
<img src="/img/logo.png">                  <!-- root-relative, the safest -->
<script src="https://cdn.example.com/lib.js"></script>

Don't forget the url(http://...) definitions inside CSS files and the inline background-image values.

Step 3 — Bulk-replace old addresses in the database

In content management systems (CMS), old posts may be full of http:// links in the database. You can use a database query to update them in bulk. Always take a backup first, then run an update similar to this:

-- Take a BACKUP first!
UPDATE contents
SET body = REPLACE(body, 'http://yourdomain.com', 'https://yourdomain.com');

Adapt the table and column names to your own schema.

Step 4 — A bulk fix: upgrade-insecure-requests

If fixing hundreds of old links one by one is hard, you can add a security header that tells the browser to automatically upgrade all HTTP requests to HTTPS. This works if an HTTPS version of the same resource exists:

# Nginx
add_header Content-Security-Policy "upgrade-insecure-requests";
<!-- or inside the HTML <head> -->
<meta http-equiv="Content-Security-Policy"
      content="upgrade-insecure-requests">

This method is not a solution for resources that don't have an HTTPS version on an external server; either replace those resources with an alternative that serves HTTPS, or move them to your own server.

Step 5 — Clear the cache and verify

After the changes, clear the browser cache and, if applicable, the CDN cache, then open the page in a private tab and confirm in F12 → Console that no warnings remain. If the lock icon has returned, the problem is solved.

Common pitfalls

  • Hardcoded addresses: http:// links embedded in theme and plugin files.
  • External ad/analytics scripts: Remove or update third-party resources that don't support HTTPS.
  • Old social media embed codes: Replace them with new, HTTPS-compatible embed codes.

Summary

Mixed content arises from HTTP resources remaining on an HTTPS page and lowers the lock. Find the culprits in the console, make the addresses https://, and back this up with upgrade-insecure-requests if needed. If you don't have a certificate yet or need to renew, generate one with our free SSL wizard and download the ZIP package.