# Mixed Content: “The page was loaded over HTTPS, but requested an insecure resource”

> The page was loaded over HTTPS, but requested an insecure resource. Why the browser blocks your http:// API call or script, and how to fix it for good.

Canonical: https://app369.com/fix/mixed-content-blocked-http-request/
Last updated: 2026-11-07

The app works on your laptop, then breaks once it is live on HTTPS: data never loads, a script or font is missing, and the console says Mixed Content, the page was loaded over HTTPS but requested an insecure resource, and the request has been blocked. Somewhere the page still asks for an http:// address. In apps built with AI tools, a frequent cause is an API address saved in an environment variable while testing. Below is what browsers block, quoted from MDN, and how to fix it. Or hand it over at a fixed price.

**Short answer**

Your HTTPS page asked for something over plain http://. Browsers block scripts, stylesheets, iframes, fonts and fetch() or XHR calls to http:// outright, so the request never reaches your server. Find the http:// address in the console message, serve that resource over HTTPS, and change the link to https:// or a relative path. Check your environment variables first: an API URL saved as http:// is a frequent cause.

## **Why the request is blocked, and the fix**

1. 01 ### **An API call or script still points at http://**
  > “Browsers mitigate the risks of mixed content by auto-upgrading image, video, and audio mixed content requests from HTTP to HTTPS, and block insecure requests for all other resource types.” [**MDN, Mixed content**](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Mixed_content) Images, audio and video get a second chance: the browser retries them over HTTPS. Everything else does not. A fetch() to your API, a script tag, a stylesheet, an iframe or a web font on http:// is blocked before it leaves the browser, so your server logs show nothing. A frequent culprit is an API address in an environment variable that was set while testing locally, such as VITE_API_URL or NEXT_PUBLIC_API_URL, and copied into the live settings.```
// blocked on an https:// page
const API = 'http://api.example.com';

// works: same request over HTTPS
const API = 'https://api.example.com';
```
2. 02 ### **An image or media file on a bare IP address**
  > “Mixed content requests that would otherwise be upgraded are blocked if the URL's host is an IP address rather than a domain name.” [**MDN, Mixed content**](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Mixed_content) The automatic upgrade only works for a domain name. An image served from an address like http://203.0.113.10/photo.png is blocked. Give the server a domain with a certificate, or move the files to storage that serves HTTPS. Images set through srcset or a <picture> element are never upgraded, so an http:// image there is blocked even on a domain name.
3. 03 ### **Hard-coded http:// links in your own code or content**
  > “Make all references to resources hosted on your domain into relative links or HTTPS links, including for downloads.” [**MDN, Mixed content**](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Mixed_content) Old links in templates, CMS content or database rows keep asking for http:// after the site moves to HTTPS. Replace them with https:// or with relative paths, so they follow the page. If your own API or file server only answers on http://, add a certificate there; changing the link alone will not help.
4. 04 ### **Find every insecure request**
  > “The developer console shows warnings when mixed content is upgraded or blocked.” [**MDN, Mixed content**](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Mixed_content) Open the page with the browser console showing and click through each screen: each warning names the blocked address. Fix those one by one, then check again in a private window. A Content-Security-Policy with upgrade-insecure-requests can make the browser try HTTPS for the rest, but it only helps when the other server answers on HTTPS.

Checked against the vendor’s docs on November 7, 2026: [MDN: Mixed content (what browsers upgrade, what they block, and how to fix it)](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Mixed_content).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**Vercel environment variables undefined**](https://app369.com/fix/vercel-environment-variables-undefined/) · [**Vite “Failed to load module script”**](https://app369.com/fix/vite-failed-to-load-module-script-mime-type/) · [**Supabase Edge Function CORS error**](https://app369.com/fix/supabase-edge-function-cors-error/)

Questions

## **More on this error**

<details>

<summary>**Why does it work on localhost but not live? **+</summary>

Locally the page itself is http://, so an http:// request is not mixed content. Once the live site is on HTTPS, every http:// request from it counts as mixed content and most of them are blocked.

</details>

<details>

<summary>**Is this the same as a CORS error? **+</summary>

No. A CORS error means the request reached the other server and the browser refused the answer. A mixed content block happens before the request is sent, so the other server never sees it. You can have both: fix the http:// address first, then check CORS.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)