Mixed Content Errors: Why Your HTTPS Site Loads Things Over HTTP (and How to Fix It)
"Mixed Content: The page was loaded over HTTPS, but requested an insecure resource." What mixed content is, why browsers block it, how to find every http:// URL, and the fixes — including apps behind a proxy that generate http links.
Your site has HTTPS and the padlock — but something's broken. A script doesn't run, an API call fails, or the padlock has a warning. In the browser console:
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS,
but requested an insecure script 'http://example.com/app.js'.
This request has been blocked; the content must be served over HTTPS.
That's mixed content: a secure page loading something over insecure HTTP.
Why browsers care
HTTPS encrypts the page so nobody between the visitor and your server can read or change it. (What is HTTPS?) If that secure page then loads a script over plain HTTP, an attacker on the same Wi-Fi could swap the script for their own — and it would run with full access to your page. The whole point of HTTPS is lost.
So browsers:
- block "active" mixed content — scripts, stylesheets, iframes,
fetch/API requests — outright; - upgrade or block "passive" content like images, audio and video. Modern Chrome tries loading them over HTTPS automatically and blocks them if that fails.
Result: missing styles, broken features, failed API calls, or images that don't show.
Step 1: Find every insecure URL
- Browser console (DevTools → Console) lists each blocked request with the exact URL. (Browser developer tools for beginners)
- Search your code for
http://:
grep -rn "http://" src/ public/
- Check your database and CMS content. Image URLs and links saved in blog posts or product descriptions often contain
http://. - Check environment variables — an
API_URL=http://...left over from development is a classic.
Step 2: Fix them
Hardcoded links in your code
Change http:// to https://. For links to your own site, use relative URLs (/images/logo.png) so they always match the page's protocol.
Avoid the old protocol-relative trick (//example.com/app.js); just use https://.
Third-party resources
If a script, font or image comes from another site, use its https:// address. If the provider doesn't support HTTPS at all in 2026, replace it — or download the file and serve it yourself.
API URLs from environment variables
If your frontend calls http://api.example.com, update the variable to https:// and rebuild (frontend variables are baked in at build time). See environment variables explained.
URLs stored in the database
Run a careful find-and-replace on the affected columns — after taking a backup. (Backups for beginners.)
The sneaky cause: your app thinks it's on HTTP
Your code has no http:// anywhere, yet your app generates http:// links — in redirects, image URLs, or OAuth callbacks.
That happens when the app runs behind a reverse proxy that handles HTTPS and forwards plain HTTP to the app. The app sees HTTP and builds URLs to match. (Reverse proxies explained.)
Fix: tell the app to trust the proxy's X-Forwarded-Proto header (in Express, app.set("trust proxy", 1)), or set your app's base URL explicitly (APP_URL=https://example.com). The same misconfiguration also causes ERR_TOO_MANY_REDIRECTS and "redirect_uri_mismatch" errors with Sign in with Google.
A safety net: upgrade-insecure-requests
You can tell browsers to automatically upgrade every http:// request on your page to https:// with a header:
Content-Security-Policy: upgrade-insecure-requests
or a meta tag:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
It's a useful safety net for old content you can't easily edit. It doesn't help if the resource isn't available over HTTPS at all. See Content Security Policy and security headers explained.
After fixing: make HTTPS permanent
Once everything loads over HTTPS, add an HSTS header so browsers always use HTTPS for your domain, even if someone types http://. Only do this once you're sure everything works over HTTPS.
The summary
- Mixed content = an HTTPS page loading resources over HTTP; browsers block or upgrade it.
- Find insecure URLs in the console, your code, your env vars and your database content.
- Use
https://or relative URLs; rebuild after changing frontend env vars. - Apps behind a proxy must trust
X-Forwarded-Protoor use an explicit HTTPS base URL. upgrade-insecure-requestsis a good safety net.
EasySpawn serves every app over HTTPS on your own domain from day one, with certificates handled automatically — so there's no "HTTP era" for insecure links to creep in from. See how it works or join the waitlist.
Related: How Automatic SSL Actually Works · CORS Errors Explained · Anatomy of a URL · Vibe Coding Security Checklist
Keep reading
"Your Connection Is Not Private" on Your Own Site: Causes and Fixes
When visitors see NET::ERR_CERT_DATE_INVALID, ERR_CERT_COMMON_NAME_INVALID or ERR_CERT_AUTHORITY_INVALID on your site, the SSL certificate is expired, for the wrong name, or incomplete. How to tell which, and how to fix each one.
What Is Cloudflare? What It Does When You Put Your Site Behind It
Cloudflare sits between your visitors and your server: DNS, a CDN, free SSL, DDoS protection and a firewall. What changes when you turn on the orange cloud, what it costs, what it can break, and whether a small app needs it.