Skip to content
SCRAWL
Technical SEOFaisal Y

Mixed Content: How to Fix HTTP on

Mixed content is an HTTPS page requesting an HTTP script, stylesheet, image, or font. Here is what browsers block, what they only warn on, and how to fix the URL.

An HTTPS page with HTTP subresources split into blocked requests and warning requests.
HTTP subresources on an HTTPS page
Use the free tool
Mixed Content Checker
List HTTP subresources on an HTTPS page, split into active and passive.

An HTTPS page that still requests something over HTTP is serving mixed content. The document is encrypted. The subresource is not. Browsers treat that split differently depending on what the subresource is. Scripts, stylesheets, iframes, and fonts get blocked. Images, audio, and video usually still load, with a warning. A plain link to an HTTP URL is a navigation, not mixed content.

This guide covers those categories, where the URLs hide in HTML and CSS, and how to fix them. The Mixed Content Checker lists what is in the server HTML. It does not replace the browser console for anything a script inserts later.

What mixed content is

Mixed content happens only when the page is HTTPS and a subresource is HTTP. If the page itself is HTTP, there is nothing to mix: the whole document is already insecure. The usual cause is a move to HTTPS that left embedded URLs alone. A template, a CMS field, or a third-party snippet still contains http://.

MDN's mixed content guide splits subresources into two groups. Active mixed content can change the page: scripts, stylesheets, iframes, objects, fetches, and fonts. Passive mixed content is what the page displays: images, audio, and video. Chrome's mixed content article uses the same split. Active requests are blocked. Passive requests are allowed with a warning, and current browsers may upgrade some of them to HTTPS on their own. Do not treat that upgrade as the fix. A host that does not serve the file over HTTPS still fails, and you will have a harder time seeing the original URL.

The URL that matters is the one the browser requests, not the one you remember typing into a preview. A root-relative path such as /js/app.js inherits the page scheme, so it stays HTTPS on an HTTPS page. A scheme-relative URL (//cdn.example/app.js) also inherits the page scheme. A literal http:// does not.

Active mixed content

Active mixed content is blocked because the insecure response could change the HTTPS page.

You will usually find it in:

  • <script src="http://...">
  • <link rel="stylesheet" href="http://...">
  • <iframe src="http://...">
  • <object data="http://..."> and <embed src="http://...">
  • an @import of an HTTP stylesheet
  • an @font-face file requested over HTTP
  • fetch, XMLHttpRequest, and WebSocket URLs written in JavaScript

A static HTML check will not see the JavaScript cases. A blocked script does not run. A blocked stylesheet does not apply. A blocked iframe stays empty. A blocked font falls back to another family. The page can look almost fine while a checkout script or a layout sheet never arrived. That is why active URLs come before images.

A form action that posts to HTTP sits in the same family. An HTTPS page that submits to http:// is either upgraded by the browser or fails. Point the action at HTTPS, or omit it so the form posts to the current page.

Passive mixed content

Passive mixed content is an image, an audio file, or a video requested over HTTP.

Typical markup:

  • <img src> and srcset
  • <video>, <audio>, and <source>
  • a video poster
  • icons (rel="icon", apple touch icons)
  • CSS url() used for backgrounds, bullets, and borders

Browsers have loaded these and printed a warning. The lock in the address bar can drop even though the HTML document is HTTPS. On a hostile network the image can still be swapped, which matters when the image is a control rather than decoration. Treat passive URLs as real work. Do them after the blocked scripts and stylesheets, not instead of them.

What is not mixed content

An <a href="http://..."> is not mixed content. Following it navigates to another page. The browser does not block the click as a mixed-content subresource. You may still want to update links on your own host so you do not send people to an insecure URL. Keep that list separate from blocked scripts. A page full of old links is not the same ticket as a page whose stylesheet is blocked.

Canonical tags, sitemap locations, and Open Graph URLs that use HTTP are also not mixed content. They are the wrong scheme for other reasons. Fix them with a canonical or social-tag check. Do not file them as blocked subresources.

Where the URL hides

View source is enough on a hand-written page. It is a weak inventory once a theme, a page builder, and a tag manager are all in play.

Work in this order:

  1. Attributes in the HTML: src, srcset, stylesheet and icon href, poster, object data, form action.
  2. CSS `url()` inside <style> blocks and style attributes.
  3. Stylesheets on your own origin. A clean HTML file can still pull http:// images from /app.css. Open that file, or use a checker that fetches a capped number of same-origin sheets. A stylesheet on another host is not inside the HTML. If the link points at a third party, open that URL yourself.
  4. The network log after JavaScript runs. A lazy-load attribute such as data-src is not a request until a script copies it into src. Tag managers inject scripts the same way.
HTML and CSS sources sorted into blocked requests, warnings, and plain links

If the console reports mixed content and the server HTML is clean, a script added the request. The HTML check is looking at a different layer. It is not a contradiction.

How to fix it

Rewrite the URL. That is the fix. Policies and headers are a backstop.

Same host. Change http://example.com/app.js to https://example.com/app.js, or to a root-relative /app.js so the page scheme is reused. Then request the HTTPS URL. A 404 means the file was never deployed on the TLS host. Editing the scheme in the template will not create the file.

Images on a CDN. Some CDNs serve the same object on HTTPS. Some old buckets do not. If HTTPS returns a successful status, update the template or the media library. If it does not, re-upload or change the CDN host. Leaving the HTTP URL because the image "still shows" keeps the page on mixed content.

Third-party widgets. A script URL that starts with http:// is active mixed content and will be blocked. If the vendor publishes an HTTPS URL, use that. If they do not, remove the widget. There is no safe way to execute an HTTP script inside an HTTPS page.

Fonts. An @font-face source over HTTP is blocked. Host the font files on your HTTPS origin, or use the vendor's HTTPS stylesheet. Read the CSS file, not only the HTML. Themes often hide the font URL in a compiled sheet.

Scheme-relative URLs. //cdn.example/app.js is not mixed content on an HTTPS page, because the browser requests HTTPS. It is still a weak habit. It hides the scheme from the next person who reads the template. Prefer https://.

Content-Security-Policy. `upgrade-insecure-requests` tells the browser to fetch those HTTP URLs as HTTPS instead. It helps while you clean templates. It does not repair a missing file. If the HTTPS URL 404s, the request fails, and the network log no longer shows the HTTP URL you needed to find. Turn the policy on after you know the HTTPS copies exist, or while you are still hunting and you accept that masking. block-all-mixed-content is the older directive that also blocks passive content. Reach for upgrade first.

HSTS. Strict-Transport-Security tells browsers to use HTTPS on later visits to your host. It does not rewrite an http:// URL on a different host. Set it once your host redirects HTTP to HTTPS and you are not intentionally serving the site in cleartext. MDN documents the header.

Fix path from an HTTP subresource URL to an HTTPS rewrite, then a HEAD check

A workable order

  1. Open the page over HTTPS and read the console. Note whether the message says the request was blocked or only warned.
  2. List the URLs in the server HTML, including CSS url() and same-origin stylesheets.
  3. Rewrite active URLs first: scripts, stylesheets, iframes, objects, fonts, and form actions.
  4. Request the HTTPS version before you ship the rewrite. A successful status is a candidate. A 404 needs a new file, not a new scheme.
  5. Rewrite images, video, and audio.
  6. Update http:// links on your own host while you are in the template. Keep them on a separate list.
  7. Add upgrade-insecure-requests only as a backstop, reload, and confirm the console is quiet.
  8. Check again after the next theme or plugin update. Mixed content often comes back as a hardcoded URL in an update.

Limits of an HTML fetch

A fetch of the HTML cannot see tags inserted by JavaScript, URLs that sit in data-src until a script promotes them, or CSS on another origin. It cannot see the logged-in page if the anonymous response is a wall. It cannot promise that a browser's automatic upgrade would succeed.

Use the Mixed Content Checker to build the list from server HTML. Use the browser to confirm the page after scripts run. Certificate details belong in an SSL check. Content-Security-Policy and HSTS belong in a response-header check. Mixed content is the URL inside the page. Those other checks are the TLS and header layer around it.

mixed contenthttpstechnical seosecurity

Frequently Asked Questions

What is mixed content?

Mixed content is an HTTPS page that requests a subresource over HTTP. The document is encrypted and the subresource is not. Browsers block scripts, stylesheets, iframes, and fonts. They warn on images, audio, and video.

Is an http link mixed content?

No. An a href that points at http is a navigation to another page. Browsers do not block it as mixed content. You can still update links on your own host so you do not send people to an insecure URL.

Does upgrade-insecure-requests fix mixed content?

It tells the browser to request the HTTPS version of those URLs. If that HTTPS URL does not exist, the request still fails. Rewrite the template, then use the policy as a backstop.

Why does the console show mixed content when the HTML looks clean?

A script may insert the tag after load, or a lazy-loader may copy a data-src into src. A fetch of the server HTML does not run JavaScript. Check the network panel on the live page.

Should I change http to https if the file 404s?

No. A 404 on the HTTPS URL means the file is not there. Upload it, or point at a host that already serves it over HTTPS. A scheme swap only works when the HTTPS response succeeds.

Related Articles

Technical SEO

Site migration SEO checklist

Most migrations don't fail because someone forgot a "best practice." They fail because one boring th…

Technical SEO

Technical SEO audit checklist

Most technical audits start in the wrong place. Someone opens a crawler, exports 4,000 "issues," and…

Tool Guides

SEO readiness checker: score any URL, fix what matters

Most technical audits start with a 4,000-row crawl export. You need something faster: is this one UR…

Technical SEO

How to Check if a Page Is Indexed by Google (and Fix It If Not)

Pages outside Google's index cannot rank. Learn what "indexed" means, how to confirm status in Searc…

Technical SEO

What Is PageRank in 2026? How Google Link Authority Works (and How to Check It)

Google retired public PageRank in 2016, but links still matter for discovery and relevance. Here's h…

Technical SEO

Broken link checker: find 404s on a page, check URL lists in bulk, and fix the right links

A broken link is a link that leads nowhere useful. Usually that means a 404, sometimes a 410, a serv…

Technical SEO

Bulk status checker: audit up to 200 URLs for 404s, redirects, and server errors

A bulk status check answers one question: for each URL in this list, what does the server return rig…

Technical SEO

How to see which AI crawlers visit your site in your server logs

robots.txt states what you want crawlers to do. Access logs show what actually hit your server: whic…

Technical SEO

How to check whether AI search bots can crawl your pages

A page can look fine in Chrome and still be a thin shell in raw HTML. AI retrieval crawlers mostly r…

Technical SEO

Custom Extraction with CSS Selectors and XPath: A Practical Guide

Fixed heading extractors stop where your audit question starts: a canonical href, a SKU in a data at…

Technical SEO

Automated Accessibility Checks: What They Catch and What They Miss

A clean automated report does not mean your page is accessible. Static HTML rules catch missing name…

Technical SEO

Soft 404s: How to Find Them and Why Google Flags Them

A soft 404 can mislead crawlers and users when missing URLs return the wrong HTTP status. Learn what…

Technical SEO

Indexability: How to Check If a Page Can Be Indexed

Learn whether a page can be indexed from server signals before you ask why Google excluded it. Statu…

Technical SEO

Googlebot Simulator: Compare Googlebot vs Browser Fetches

Learn when to compare Googlebot and Chrome fetches, how to read a side-by-side diff, and what Scrawl…

Technical SEO

How to Find Any Site's XML Sitemap

Learn where sitemaps usually live, how robots.txt Sitemap lines work, and how to discover index and…

On-Page SEO

What Is a PAA Box? How People Also Ask Works in Google Search

A PAA box is the People Also Ask list Google shows for many searches: related questions that open in…

Technical SEO

Robots.txt Explained: How Allow, Disallow and Wildcards Really Work

Robots.txt tells crawlers which URLs they may fetch. It does not remove pages from Google's index by…

On-Page SEO

Google AI Overviews: What They Are and How to Get Your Content Cited

AI Overviews are Google's generated answer blocks on some searches. They cite a small set of sources…

Technical SEO

Schema Checker Guide: How to Validate JSON-LD and Microdata

A schema checker reads the structured data on a page and tells you whether a machine can parse it an…