Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure resource
The browser blocked an HTTP resource (image, script, iframe) loaded from your HTTPS Lightning page. Modern browsers refuse to load mixed content for security. Switch the resource URL to HTTPS, or host it within Salesforce as a static resource.
Also seen asMixed Content·loaded over HTTPS, but requested an insecure·Mixed Content blocked·insecure resource lightning
You're previewing a Lightning page that needs to display a partner company's logo. The image element points to http://partner-cdn.example.com/logo.png. The Lightning page loads, the layout is correct, but where the logo should be, you see a broken-image icon. The browser console reads Mixed Content: The page at 'https://yourdomain.lightning.force.com/...' was loaded over HTTPS, but requested an insecure image 'http://partner-cdn.example.com/logo.png'. This request has been blocked; the content must be served over HTTPS.
What the browser is enforcing
Modern browsers refuse to load HTTP resources from HTTPS pages. The policy is called "mixed content blocking" and it exists because an HTTP resource on an HTTPS page defeats the security guarantee the user thinks they have. The padlock icon in the address bar implies that everything on the page is private and tamper-proof. An HTTP request to a third-party server is neither, because the request and response travel in cleartext over the network and a man-in-the-middle can read or modify them.
Browsers split mixed content into two categories:
- Active mixed content (scripts, stylesheets, iframes, fetch/XHR requests): blocked outright. The browser refuses to load these because they can change the behavior of the page.
- Passive mixed content (images, videos, audio): older browser versions sometimes allowed these with a warning. Modern browsers block them too. The current rule across Chrome, Firefox, Safari, and Edge is "block everything."
Salesforce Lightning pages always serve over HTTPS. Every URL you reference from a Lightning component must also be HTTPS, or the browser blocks it.
The broken example
A Lightning Web Component that wants to render a partner logo:
<!-- partnerLogo.html -->
<template>
<div class="slds-p-around_small">
<img src="http://partner-cdn.example.com/logo.png" alt="Partner logo">
</div>
</template>
The component compiles. The bundle deploys. The page renders. The image doesn't.
Fix 1: switch to HTTPS
The simplest fix is almost always available: the same resource is served over HTTPS by the same provider. Almost every public CDN, image host, and partner web server offers HTTPS in 2026. The fix is one character:
<template>
<div class="slds-p-around_small">
<img src="https://partner-cdn.example.com/logo.png" alt="Partner logo">
</div>
</template>
If you can't verify HTTPS support, open the same URL with https:// in a browser. If it loads, you're done. If it returns a certificate error or a 404, the host doesn't have HTTPS at that path. Move to one of the other fixes.
Fix 2: host the resource as a Salesforce Static Resource
For images, fonts, small JavaScript libraries, or any other static asset, the cleanest answer is to upload the file to Salesforce as a Static Resource. The resource is served from the same Salesforce HTTPS origin as the Lightning page, which sidesteps mixed content entirely.
Steps:
- Setup → Static Resources → New.
- Upload the file.
- Set Cache Control to Public if the asset can be shared across users.
- Save and note the resource name.
In the LWC:
// partnerLogo.js
import { LightningElement } from 'lwc';
import PARTNER_LOGO from '@salesforce/resourceUrl/PartnerLogo';
export default class PartnerLogo extends LightningElement {
logoUrl = PARTNER_LOGO;
}
<!-- partnerLogo.html -->
<template>
<div class="slds-p-around_small">
<img src={logoUrl} alt="Partner logo">
</div>
</template>
The import resolves at deploy time to the Salesforce-hosted URL, which is HTTPS. The component loads the image without triggering mixed content blocking.
Static Resources have a 5 MB per-file cap, with up to 250 MB total per org for the resource itself. For images, that's plenty. For larger assets (video, datasets), use Salesforce Files or a Content Delivery Network with HTTPS support.
Fix 3: proxy through Apex for genuinely dynamic content
If the resource is dynamic (generated per-user, per-request, by an external system that only speaks HTTP), the answer is to route the request through an Apex @AuraEnabled method. The Apex callout runs server-side, on Salesforce infrastructure, which can talk to HTTP endpoints. The Apex method returns the data to the LWC, which displays it without a direct browser request to the HTTP server.
public class PartnerLogoProxy {
@AuraEnabled(cacheable=true)
public static String fetchLogo() {
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Partner_HTTP/api/logo');
req.setMethod('GET');
HttpResponse res = new Http().send(req);
if (res.getStatusCode() != 200) {
throw new AuraHandledException('Logo fetch failed: ' + res.getStatus());
}
Blob body = res.getBodyAsBlob();
return 'data:image/png;base64,' + EncodingUtil.base64Encode(body);
}
}
// partnerLogo.js
import { LightningElement, wire } from 'lwc';
import fetchLogo from '@salesforce/apex/PartnerLogoProxy.fetchLogo';
export default class PartnerLogo extends LightningElement {
@wire(fetchLogo) logo;
get logoSrc() {
return this.logo?.data;
}
}
The image renders from a data URL embedded in the page. No mixed-content request. The cost is added latency (every render triggers an Apex callout) and the Apex callout governor budget (100 per transaction). Use this pattern only when the other two fixes don't apply.
The callout:Partner_HTTP syntax references a Named Credential, which Salesforce manages with its own HTTP client. Named Credentials bypass the browser's mixed-content rules because the request originates from Salesforce's servers, not the user's browser.
The fixed example
Take the broken partnerLogo and ship a production version using the static-resource path:
// partnerLogo.js
import { LightningElement, api } from 'lwc';
import PARTNER_LOGOS from '@salesforce/resourceUrl/PartnerLogos';
export default class PartnerLogo extends LightningElement {
@api partnerSlug = 'acme';
get logoSrc() {
return `${PARTNER_LOGOS}/${this.partnerSlug}.png`;
}
}
<!-- partnerLogo.html -->
<template>
<div class="slds-p-around_small">
<img src={logoSrc} alt="Partner logo">
</div>
</template>
The PartnerLogos static resource is uploaded as a zipped folder containing one PNG per partner slug. The LWC composes the path at render time. The browser sees an HTTPS URL on the same origin as the Lightning page. No mixed content, no broken images, no console errors.
Iframes are the trickiest
A common scenario: an old internal tool runs at http://legacy.internal.example.com/. Someone wants to embed it inside a Lightning page via an iframe. Mixed content blocking refuses:
<!-- Blocked by mixed-content policy -->
<iframe src="http://legacy.internal.example.com/" width="800" height="600"></iframe>
For iframes, the workarounds are heavier. The legacy system needs to either start serving HTTPS, sit behind a reverse proxy that adds HTTPS, or get embedded via a popup rather than an iframe. The cleanest path is to fix the legacy system; the cheapest path is to reverse-proxy it.
A simple Nginx-based reverse proxy in front of the HTTP system terminates HTTPS to the browser and forwards HTTP requests to the backend. The browser sees HTTPS; the backend remains untouched. This is the same trick CDNs use to put HTTPS in front of HTTP-only origins.
CSP is a separate gate
Don't conflate mixed content blocking with the org's Content Security Policy (CSP). They're independent rules.
| Error | Cause |
|---|---|
Mixed Content: ... insecure resource | HTTP URL on HTTPS page; browser-enforced |
Refused to connect to ... because it violates the following Content Security Policy directive | URL not in Salesforce CSP Trusted Sites; Salesforce-enforced |
Both must be satisfied. A URL that is HTTPS but not in Trusted Sites is blocked by CSP. A URL that is in Trusted Sites but is HTTP is blocked by mixed content. The fix for each is different:
- Mixed content: change the URL to HTTPS (or proxy).
- CSP: add the URL to Setup → CSP Trusted Sites with the appropriate "connect-src" or "img-src" category.
A new external integration usually requires both: add the domain to Trusted Sites and ensure all references use HTTPS.
Diagnostic walk for a new mixed-content report
When a developer says "this image isn't loading on the production Lightning page":
- Open the page in Chrome with DevTools. Inspect the Console tab.
- Filter to "Errors" and look for
Mixed Content. - The error names the exact resource URL and the page URL that requested it.
- Confirm the resource URL is HTTP, not HTTPS.
- Confirm the same URL with HTTPS loads in the browser (paste into a new tab).
- If yes: change the LWC reference to the HTTPS URL. Deploy.
- If no: pick one of the other fixes.
The walk takes about three minutes. The fix is usually a one-character change in source.
When the resource URL is dynamic and produced by a managed package
A managed package you don't control may emit HTTP URLs into a Lightning page. The package's components reference an HTTP endpoint that the vendor hasn't yet upgraded. You see mixed-content errors and can't change the package's source.
Three options:
- Log a support case with the package vendor. Most respond within a release cycle if it's a security regression.
- Override the component locally. If the package exposes a "skin" or "template" component you can swap in, replace the offending reference at your level.
- Disable the package's affected feature. Most managed packages have feature toggles in their settings page; disabling the HTTP-dependent feature is the safest interim fix.
Don't override the page's CSP to allow mixed content. The CSP is what makes mixed-content blocking enforced; relaxing it doesn't actually re-enable the HTTP request anyway (browser-level mixed content blocking wins), and you'd be weakening security for no fix.
A short history note
Mixed content blocking arrived in browsers around 2010-2014 in stages. Salesforce Lightning launched fully HTTPS-only in 2015. Code from earlier era (Classic Visualforce, on-premise integrations) was often written assuming HTTP was fine. As those systems migrated to Lightning, mixed content surfaced as a recurring class of issue.
The trajectory continues. Browsers are progressively tightening: insecure form submissions, insecure favicons, and other passive content are joining the block list. Code that uses HTTPS everywhere ages well; code with even a single HTTP URL drifts toward broken as browser versions advance.
The investment in fixing every HTTP reference, even passive ones, is small now and saves a series of future incidents as browser policy tightens. Treat the appearance of Mixed Content in any console as a P3 bug to fix in the next sprint, not a known-issue to live with.
Catching this in development before users see it
Add a lint rule to your repository that flags HTTP URLs in LWC HTML and JS source. The eslint-plugin-no-http-url package (and similar) scan strings for http:// patterns and warn at lint time. Wire it into CI and the bug class disappears at PR time.
For a quick one-time audit of an existing codebase, a shell grep does the job:
grep -rn 'http://' force-app/main/default/lwc/ force-app/main/default/aura/
Every match is a candidate for an HTTPS rewrite. Most are quick fixes; a few will need the Static Resource or proxy approach. The audit takes an hour; the user-facing payoff is permanent.
Further reading from Salesforce
- Salesforce Help: Mixed Content Resources
- Lightning Web Components Developer Guide: Use Static Resources
- Salesforce Help: CSP Trusted Sites
- Apex Developer Guide: HTTP Classes
- Salesforce Help: Named Credentials
Related dictionary terms
Share this fix
Related Lightning · LWC errors
@wire(getRecord, ...) requires the fields property
Lightning · LWCYou used `getRecord` from `lightning/uiRecordApi` without specifying which fields to fetch. LDS doesn't auto-fetch all fields like an old-sc…
Action failed: c:myComponent$controller$myAction [<JS error message>]
Lightning · LWCAn Aura component's client-side JavaScript controller threw an exception. The error message is wrapped in `Action failed: c:component$contro…
Cannot find component: c:myComponent
Lightning · LWCThe Lightning runtime tried to instantiate a component by name and the platform doesn't have it — the bundle didn't deploy, the namespace pr…
Cannot read properties of undefined (reading 'X') — in LWC component lifecycle
Lightning · LWCPlain JavaScript TypeError, but in LWC it almost always means a `@wire` result was read in `connectedCallback` or `renderedCallback` before …
Lightning component cannot be created: c:myComponent
Lightning · LWCThe framework couldn't instantiate a Lightning component at runtime — usually a missing dependency, a permission gap, or a static-resource l…