Security · Explainer

Mixed content

You moved the site to HTTPS and the padlock still will not stay. Usually one forgotten http reference is doing it, and depending on what kind of asset it is, the browser either warns the visitor or silently refuses to load it.

What counts as mixed content

A secure page that pulls in an insecure resource. The page is HTTPS; something it loads is not.

The connection to your server is encrypted, but an asset referenced over http:// travels in the clear and can be read or modified in transit. Since the page is only as trustworthy as everything it loads, browsers treat this as a broken security state rather than a partial one. The practical symptom is familiar: the padlock disappears or is marked as not fully secure, and the cause is almost never the certificate that people usually go looking at first.

Active and passive are treated very differently

One is blocked outright, the other is allowed with a warning. Knowing which is which explains most confusing symptoms.

Active mixed content is anything that can change the page: scripts, stylesheets, iframes, XHR and fetch requests. A tampered script could rewrite the whole document, so browsers block it. The visible result is a page missing functionality or styling for no obvious reason, with the explanation only in the console.

Passive mixed content is images, video and audio. A tampered image is misleading but cannot take over the page, so browsers generally load it and downgrade the security indicator. The page looks right and the padlock does not.

This is why a broken layout and a missing padlock can have the same root cause and look like unrelated problems. Both are mixed content; they differ only in what the asset was allowed to do.

Where the http references hide

Templates are usually clean. The leftovers are in content and configuration.

Old content in the database

Articles written before the HTTPS migration often contain hardcoded http:// image sources in the body, and no template change reaches them.

These need a content-level find and replace, done carefully and with a backup, not a template fix.

Third-party embeds

Old embed codes for maps, video players, fonts and widgets frequently use http. Some vendors still publish http snippets in their documentation.

Most have an https equivalent at the same path. Where one does not, the honest options are to replace the vendor or drop the embed.

Absolute internal links

Internal references written as full http://yoursite.com/... URLs stay insecure even after the site moves, and they add an extra redirect hop on every request.

Use protocol-relative or root-relative paths internally so they follow whatever scheme the page is served on.

Configuration and feeds

Site URL settings, canonical tags, sitemap entries, RSS feeds and Open Graph image URLs are all easy to miss because they are not part of the visible page.

A canonical or og:image still on http is the kind of thing that survives a migration for years without anyone noticing.

Fixing it properly

Find every reference first, then decide what to do with each one.

Spot-checking the homepage is not enough: mixed content is usually concentrated in older content pages that nobody opens with the console up. A site-wide crawl that reports insecure references per page is the only reliable way to get the full list, and it usually turns out to be a short one clustered in a few places.

upgrade-insecure-requests in your Content Security Policy tells browsers to fetch http references over https automatically, which is a reasonable safety net. Treat it as a net and not the repair: it does nothing if the asset genuinely has no https version, and it leaves the wrong URLs in your content where they keep being copied forward. Fix the references, then keep the policy for whatever slips through. See security headers for how that directive fits with the rest.

How the audit finds it

Two separate checks, because a mixed-content asset and a plain http link are different failures.

On every crawled page served over https, the audit scans the images, scripts and stylesheets referenced on that page for any URL starting with http://. Separately, it checks internal links on https pages that point at an http:// version of your own site, which won't downgrade the padlock the way an asset does, but does add an avoidable redirect hop on a link entirely within your control to fix. Both are reported per page, so you get the exact URL rather than a single site-wide count.

Mixed content questions, answered

How do I check a single page for mixed content?

Open the browser console: Chrome and Firefox both log a specific warning or error naming the exact insecure URL. For a whole site, a crawl that records every http:// reference across images, scripts and stylesheets is the practical way to find them all, since they're usually scattered through old content rather than sitting in one template.

Why does my http image still show if the browser flags it?

Images, video and audio are passive mixed content: a tampered one can mislead but can't take over the page, so browsers generally load it while downgrading the padlock. Scripts, stylesheets, iframes and fetch/XHR requests are active mixed content and get blocked outright, since a tampered script could rewrite the whole document.

Will just changing http:// to https:// in the URL fix it?

Usually, since most modern hosts and CDNs serve the same asset at the https path too. Where that's true, a straightforward find-and-replace clears it. Where the host never enabled TLS or the asset moved, you need a working https source, not just a changed protocol on a dead one.

Does mixed content hurt rankings directly?

There's no separate mixed-content penalty, but it undermines the HTTPS signal Google does use, and it visibly damages trust and click-through, which affects behaviour Google can observe indirectly. See security for how this sits alongside the certificate checks.

Can a CSP directive fix this by itself?

upgrade-insecure-requests tells the browser to rewrite http references to https automatically, which catches most cases. It's a safety net, not a fix: it does nothing if the asset genuinely has no https version, and the wrong URL stays in your source ready to cause the same problem if the directive is ever removed.

Where do the last few references usually hide?

In places nobody rechecks after the main migration: old posts with hardcoded image URLs in the body, embed codes copied from vendor docs years ago, a canonical tag or og:image left on http, and RSS feeds that never got regenerated. A template-level fix cannot reach any of these.

Find every insecure reference on your site

Free to start. Reports HTTPS pages loading HTTP assets, page by page, so you can see exactly where the padlock breaks.

Start my free audit