Glossary

Mixed content

Mixed content is a resource loaded over plain HTTP by a page that was itself served over HTTPS. Browsers block the dangerous cases outright — scripts, stylesheets, frames and fetches, which can alter the page — and increasingly upgrade or block the passive ones such as images. Its effect is that the page's security guarantee is only as strong as its weakest subresource, which is why the padlock is withheld regardless of how well TLS is configured.

Active and passive

Active mixed content can change the page: scripts, stylesheets, iframes, XMLHttpRequest and fetch requests, web workers. An attacker who substitutes one controls the page entirely.

Passive mixed content is displayed but cannot execute: images, video, audio. Substituting one changes what the visitor sees and can be used to mislead, but it cannot read the page or the session.

Browsers block active mixed content unconditionally, and have done for years. The resource simply does not load, and the console records why.

Passive mixed content has moved from being merely flagged to being automatically upgraded to HTTPS, and blocked when the upgrade fails.

Where it comes from

Absolute URLs hard-coded with `http://` in templates, database content or configuration, usually written before the site moved to HTTPS.

Content management systems that stored full URLs in article bodies at publication time, which a site-wide search and replace is the usual remedy for.

Third-party embeds — older advertising, analytics or widget scripts — whose provider never migrated.

Redirects: a resource requested over HTTPS that redirects to HTTP counts as mixed content at the point of the redirect.

Canonical tags, Open Graph image URLs and structured data references written with `http://`, which do not break the page but do publish plain-HTTP addresses to everything that reads the markup.

What a browser shows

The padlock is replaced by a neutral or warning indicator, and the site is presented as not fully secure.

Blocked active content produces a console message naming the URL, which is the fastest path to finding it.

Functionality breaks visibly when the blocked resource was a script or a stylesheet — the page renders unstyled, or an interactive element does nothing.

There is no HTTP status involved, so server logs contain nothing about it. The decision happened entirely in the browser.

How to find and fix it

Open the page and read the console. Every blocked or upgraded resource is named there.

Prefer protocol-relative fixes only as a stopgap; the correct change is an absolute `https://` URL, since protocol-relative URLs behave badly outside a browser.

`Content-Security-Policy: upgrade-insecure-requests` instructs the browser to rewrite HTTP subresource requests to HTTPS, which handles content you cannot easily edit.

For a whole site, search the templates and the database for `http://` followed by your own domain, and for known third-party hosts.

Set `Content-Security-Policy-Report-Only` with a reporting endpoint to collect mixed content from pages real visitors load, which covers the resources injected at runtime that a crawl of the markup never sees.

Frequently asked questions

Why is my padlock missing when my certificate is valid?
Almost always mixed content. The page's guarantee is limited by its weakest subresource, so a single plain-HTTP reference removes the indicator.
Are images over HTTP still allowed?
Browsers now upgrade passive mixed content to HTTPS automatically and block it when the upgrade fails, so it is no longer reliably displayed.
What does upgrade-insecure-requests do?
It is a Content-Security-Policy directive telling the browser to rewrite HTTP subresource requests to HTTPS before sending them.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website