Moving a website from HTTP to HTTPS is an important security upgrade, but installing an SSL certificate is only one part of the process. A website can have a valid certificate, display an HTTPS URL, and still contain resources that are being requested over an insecure HTTP connection. When that happens, browsers may report a mixed content warning, block certain resources, or prevent parts of the page from working correctly.
Mixed content is particularly common after website migrations because URLs can exist in many different places. An old image URL may be stored inside a database, a JavaScript file may still call an HTTP API, a stylesheet may reference an insecure font, or a third party plugin may load an outdated HTTP resource. In larger applications, the problem can even come from reverse proxy configuration or dynamically generated URLs.
The important point is that a mixed content warning does not necessarily mean your SSL certificate is defective. The certificate can be working perfectly while individual resources on the page are still using HTTP.
This guide explains how mixed content works, why it happens, how to identify the exact resource responsible, and how to fix the underlying problem instead of simply hiding the warning.
What Is Mixed Content?
Mixed content occurs when an HTTPS page attempts to load a resource through an insecure HTTP connection. For example, the main page might be loaded from:
https://example.com
while one of its resources is requested from:
http://example.com/images/banner.jpg
The browser is therefore dealing with two different security states on the same page. The main document has been delivered through an encrypted connection, while the image has been requested through an unencrypted one.
The problem becomes much more serious when the insecure resource is something that can influence the behavior of the page. An HTTP JavaScript file, stylesheet, iframe, API response, or web font can potentially affect what the user sees or what the application does. The W3C mixed-content specification explains that loading insecure subresources weakens the security guarantees provided by HTTPS because those resources can potentially be observed or modified in transit.
Modern browsers therefore do not treat every HTTP resource in exactly the same way. Some resource types may be automatically upgraded to HTTPS, while others are blocked. MDN documents these categories and recommends serving all resources through secure origins.
Why Does Mixed Content Appear After Installing an SSL Certificate?
The biggest misunderstanding is assuming that an SSL certificate changes every URL on a website from HTTP to HTTPS.
It does not.
An SSL/TLS certificate allows a server to establish an authenticated HTTPS connection for a hostname. It does not rewrite URLs stored in your HTML, database, CSS, JavaScript, plugins, themes, CDN settings, or application configuration.
For example, before migration a page might contain:
<img src="http://example.com/images/product.jpg">
<script src="http://example.com/js/app.js"></script>
After installing the certificate, the page itself may become:
https://example.com/product
but the underlying resources can still contain the original HTTP references.
This is why an HTTPS migration needs to be treated as a website-wide URL and infrastructure migration, rather than simply a certificate installation.
If you are already dealing with broader HTTPS configuration problems, it is useful to distinguish mixed content from other browser-side problems such as an invalid URL error in Chrome. The two can sometimes appear together during a poorly completed migration, but they have different technical causes.
How Browsers Handle Mixed Content
Browsers have become increasingly strict about insecure resources loaded from secure pages.
Resources that can significantly alter page behavior are generally blocked when requested through HTTP. Other resources, such as certain images, audio, or video requests, may be automatically upgraded to HTTPS when possible. MDN currently describes these as upgradable content and blockable content rather than relying on the older active/passive terminology.
This distinction matters when troubleshooting because you may encounter two different outcomes.
A browser might successfully retrieve:
http://example.com/image.jpg
by upgrading the request to:
https://example.com/image.jpg
while completely blocking:
http://example.com/app.js
The fact that an image appears to work therefore does not mean that the website is free from mixed content.
A useful security objective is to make the original resource reference HTTPS rather than relying on browser upgrades.
How to Find the Exact Mixed Content Warning
The fastest way to diagnose a mixed-content problem is usually through browser developer tools.
Open the affected HTTPS page in Chrome, press F12, and inspect the Console. Reload the page and look for messages containing terms such as:
Mixed Content
blocked
insecure
HTTP
HTTPS
The message often identifies the resource that caused the warning.
For more difficult cases, open the Network panel before reloading the page. Chrome records requests made while DevTools is open and provides information such as the request URL, resource type, status, and initiator. The Initiator information is particularly valuable because it can help you trace a problematic request back to the code or resource that generated it.
Chrome’s Network panel can also filter requests by properties such as scheme:http and mixed-content, making it much easier to isolate insecure requests on a large page.
A practical Chrome investigation
Use this sequence instead of simply viewing the page source:
- Open the affected HTTPS page.
- Open DevTools and select Network.
- Enable the recording option if necessary.
- Reload the page.
- Filter for insecure HTTP requests.
- Click the suspicious request.
- Check its Headers, Initiator, and response information.
- Determine whether the URL came from HTML, CSS, JavaScript, a plugin, a theme, or a third-party service.
- Fix the original source and reload the page.
- Repeat the test until the insecure requests are gone.
The Initiator column is particularly useful when the URL does not appear directly in the page HTML. Chrome can show which script or resource caused a request, which makes dynamically generated mixed content much easier to trace.
The Most Common Causes of Mixed Content and How to Fix Them
1. Hard-Coded HTTP URLs in HTML
The simplest cause is an HTTP URL directly embedded in the page.
For example:
<img src="http://example.com/images/logo.png">
or:
<script src="http://example.com/js/main.js"></script>
If the resource is available over HTTPS, change the original reference rather than depending on a redirect:
<img src="https://example.com/images/logo.png">
and:
<script src="https://example.com/js/main.js"></script>
This is usually straightforward when the resource belongs to your own domain. The more difficult situation occurs with third-party resources because you first need to confirm that the provider actually supports HTTPS.
If an external service does not offer a secure endpoint, changing http:// to https:// will not solve the problem. You need to replace the service, use a supported HTTPS endpoint, or remove the dependency.
2. Old HTTP URLs Stored in WordPress
WordPress websites frequently develop mixed-content problems because URLs can be stored in the database independently of the primary WordPress URL.
An old image inserted into a blog post may still reference:
http://example.com/wp-content/uploads/image.jpg
even after the site’s main address has been changed to HTTPS.
The same problem can exist in widgets, page builders, custom fields, theme settings, menus, plugin configurations, and older content.
Start by checking Settings → General and confirm that both the WordPress Address and Site Address use HTTPS. Then investigate older content if the warnings remain.
Before performing a database-wide replacement, create a complete backup. Be especially careful with serialized WordPress data because a simplistic search-and-replace operation can damage structured values.
A controlled URL migration should therefore identify the old references first, replace them using a WordPress-aware method, clear the relevant caches, and then verify the result through the browser rather than assuming the replacement worked.
3. Images That Still Use HTTP
Images are a common source of mixed-content warnings because they may have been inserted years before the HTTPS migration.
A page can therefore contain:
<img src="http://cdn.example.com/photo.jpg">
while everything else appears secure.
The important thing is not just to inspect ordinary <img> elements. Check responsive image attributes such as srcset, lazy-loading implementations, CSS backgrounds, sliders, galleries, and JavaScript-generated image URLs.
This matters because an image can be requested dynamically after the initial page load. If the warning only appears after scrolling, opening a menu, loading a slider, or performing another interaction, inspect the Network panel while performing that action rather than relying only on the initial HTML.
Modern browser behavior also means that some image requests may be automatically upgraded to HTTPS, so the absence of a visibly broken image does not necessarily prove that the original URL is correct.
4. HTTP JavaScript Files
JavaScript is one of the most important mixed-content problems because an insecure script can potentially alter the entire page.
For example:
<script src="http://cdn.example.com/application.js"></script>
should use an HTTPS endpoint where available:
<script src="https://cdn.example.com/application.js"></script>
If the script belongs to a third-party provider, verify its current HTTPS URL rather than making the change blindly.
This is particularly important for analytics, payment integrations, chat widgets, advertising systems, customer-support tools, and marketing platforms. A single outdated third-party script can cause a secure page to generate a mixed-content warning.
If the script is no longer required, removing it can be better than maintaining an unnecessary dependency.
5. HTTP Stylesheets and Resources Inside CSS
Changing a stylesheet URL is only part of the solution because CSS can itself contain insecure resource references.
For example:
<link rel="stylesheet" href="https://example.com/css/style.css">
may be secure while the stylesheet contains:
background-image: url("http://example.com/images/bg.jpg");
Fonts can create a similar problem:
@font-face {
font-family: "ExampleFont";
src: url("http://cdn.example.com/font.woff2");
}
When investigating CSS-related mixed content, therefore, inspect both the stylesheet reference and the contents of the stylesheet.
This is especially important for websites using themes, page builders, design frameworks, or generated CSS files where resource URLs may not be visible in the main HTML.
6. HTTP API Requests
Modern websites frequently load information after the initial page has rendered.
A page might be loaded securely at:
https://example.com/dashboard
while JavaScript calls:
fetch("http://api.example.com/orders")
The browser can block the request because the secure page is attempting to communicate with an insecure HTTP endpoint.
The solution is not simply to modify the frontend if the API itself does not support HTTPS. The API server must be configured to accept secure connections, with a valid certificate and appropriate TLS configuration.
This becomes especially important for:
- Login and authentication systems
- Ecommerce applications
- Customer dashboards
- Payment workflows
- Search systems
- SaaS applications
- Mobile and web APIs
If the application uses a reverse proxy or load balancer, also verify that the backend correctly understands the original request scheme. An application that incorrectly believes a visitor connected through HTTP can generate HTTP URLs even when the public-facing connection is HTTPS.
7. Third-Party Plugins and Themes
A website can be correctly configured while an old plugin or theme introduces HTTP resources.
This is common with older software that contains hard-coded URLs or assumes the website is still operating over HTTP.
If the warning began after enabling a plugin, updating a theme, or adding a new integration, compare the Network activity before and after the change.
A useful troubleshooting approach is to temporarily disable the suspected component in a staging environment and reload the affected page. If the warning disappears, inspect the component’s configuration and determine whether an update or replacement is available.
Do not immediately edit plugin source files as a permanent fix. A future update can overwrite the modification, bringing the problem back.
If your site is already experiencing broader browser-side failures, also check whether the underlying issue is actually a Google Chrome critical error rather than mixed content alone.
8. CDN and External Asset Configuration
Content delivery networks add another possible source of mixed content.
Your primary website may use:
https://example.com
while assets are being requested from:
http://cdn.example.com
If the CDN supports HTTPS, update the site’s asset configuration to use the secure hostname.
Also inspect cache and rewriting rules because a CDN can continue serving an older version of a page or asset reference after the origin has been corrected.
When troubleshooting CDN-related mixed content, verify the entire path:
Browser
↓
HTTPS website
↓
HTTPS CDN
↓
Origin server
Do not assume that because the origin server has a valid certificate, the public CDN endpoint is correctly configured.
9. Reverse Proxy and Load Balancer Configuration
This is one of the less obvious causes and is particularly relevant to larger websites.
Consider an architecture where HTTPS terminates at a load balancer:
Browser
|
HTTPS
|
Load Balancer
|
HTTP
|
Application Server
The internal HTTP connection is not automatically a mixed-content problem because the browser is not directly making that internal request.
However, the application can become confused about the original protocol. If it does not correctly understand forwarded protocol information, it may generate URLs such as:
http://example.com/script.js
even though the visitor reached the website through HTTPS.
The fix is normally found in the proxy or application configuration rather than in the certificate itself. Review how the infrastructure communicates the original request scheme to the application and make sure URL generation respects HTTPS.
This problem is particularly easy to miss because manually inspecting the certificate can show that HTTPS is functioning correctly while the application continues generating insecure links.
Mixed Content vs an SSL Certificate Error
Mixed content is often confused with a certificate problem because both can appear after an HTTPS migration.
They are not the same.
An SSL/TLS certificate problem affects the secure connection itself. Examples include an expired certificate, hostname mismatch, invalid trust chain, or other TLS negotiation problems.
Mixed content occurs when the secure page is already being loaded but the page subsequently requests another resource over an insecure protocol.
A simplified difference is:
| Problem | What is failing? | Typical example |
|---|---|---|
| Certificate error | HTTPS connection or certificate validation | Expired certificate |
| TLS configuration error | Secure protocol negotiation | Unsupported TLS configuration |
| Mixed content | Resource loaded from an HTTPS page | HTTPS page requesting HTTP JavaScript |
| HTTP redirect issue | Visitor is not consistently reaching HTTPS | HTTP homepage redirects to HTTPS |
This distinction prevents a common mistake: purchasing or reinstalling another SSL certificate when the actual problem is an outdated resource URL.
If you need to understand the wider relationship between certificates and secure connections, understanding TLS/SSL provides useful background before troubleshooting individual browser warnings.
How to Fix Mixed Content in WordPress Without Breaking the Site
A WordPress migration should be handled in stages rather than by immediately replacing every http:// string.
First confirm that the site’s primary URLs use HTTPS. Then identify the remaining insecure resources through browser developer tools and determine where those URLs originate.
For database content, create a backup before making replacements. If a URL occurs inside serialized data, use a tool or migration method capable of safely handling WordPress serialization rather than executing a simplistic SQL replacement.
After the replacement:
- Clear WordPress caching.
- Clear any CDN cache.
- Clear server-side page cache.
- Open the page in a private browsing window.
- Inspect the Console.
- Inspect Network requests.
- Test forms, menus, sliders, login, checkout, and other dynamic features.
- Repeat the process for important pages rather than checking only the homepage.
This matters because fixing the homepage does not guarantee that older posts, landing pages, checkout pages, or dynamically generated content are clean.
Do HTTP-to-HTTPS Redirects Fix Mixed Content?
Redirecting HTTP requests to HTTPS is important for an HTTPS migration, but it should not be considered the primary solution to mixed content.
Suppose the HTML contains:
http://example.com/script.js
and the server responds with a redirect to:
https://example.com/script.js
The original page is still requesting an HTTP resource.
For certain types of resources, browsers may upgrade or block the request before the redirect can provide the behavior you expected. The safer approach is to make the page directly reference the HTTPS URL.
Redirects remain valuable for old links, bookmarks, search-engine references, and visitors who still type the HTTP version of your website.
They should complement a proper HTTPS migration rather than replace one.
Can Content Security Policy Automatically Fix Mixed Content?
There is a useful security control called:
upgrade-insecure-requests
This Content Security Policy directive instructs compatible browsers to treat insecure resource URLs as if they had been changed to HTTPS. MDN specifically describes the directive as useful for sites with large numbers of legacy insecure URLs that still need to be rewritten.
For example:
Content-Security-Policy: upgrade-insecure-requests;
This can be valuable during an HTTPS migration, particularly on large sites where old URLs may be difficult to locate immediately.
However, it should not become an excuse to leave the underlying URLs untouched.
If the resource does not actually support HTTPS, the upgraded request will fail rather than falling back to HTTP. MDN explicitly notes this behavior.
A sensible strategy is therefore:
Find insecure URLs
↓
Fix the original references
↓
Use upgrade-insecure-requests as an additional safeguard
↓
Monitor for remaining problems
Also avoid relying on the deprecated block-all-mixed-content directive for new implementations. MDN now marks that directive as deprecated and recommends modern approaches instead.
Should You Use HSTS Alongside Mixed Content Fixes?
HSTS, or HTTP Strict Transport Security, addresses a related but different problem.
With HSTS, a browser can be instructed to use HTTPS when communicating with a domain rather than repeatedly starting with HTTP.
It is therefore useful for enforcing HTTPS at the connection level, while upgrade-insecure-requests addresses insecure resource references within a page.
MDN’s TLS configuration guidance recommends considering HSTS together with upgrade-insecure-requests for appropriate HTTPS deployments.
Do not enable HSTS casually on a domain with broken HTTPS subdomains or incomplete infrastructure. A poorly planned HSTS rollout can make previously accessible HTTP endpoints unreachable over the browser’s enforced HTTPS behavior.
How to Find Mixed Content That Loads Dynamically
Some of the hardest mixed-content problems do not exist in the initial HTML.
JavaScript may generate the URL only after the user:
- Clicks a button
- Opens a menu
- Submits a form
- Scrolls down
- Opens a popup
- Loads a product filter
- Starts a video
- Opens a customer dashboard
In such cases, viewing the page source is not enough.
Open Chrome DevTools, start recording in the Network panel, and perform the action that triggers the problem. When the insecure request appears, inspect its Initiator information.
Chrome documents that the Network panel can identify the initiator responsible for a request and can link script-generated requests back to their source.
This can turn a vague warning into something actionable:
Mixed content
↓
HTTP API request
↓
JavaScript file
↓
Specific function
↓
Application configuration
At that point, you can fix the actual source instead of repeatedly changing generated HTML.
What About HTTP Fonts and Background Images?
These resources are easy to miss because they may not appear as ordinary HTML elements.
A stylesheet can contain:
background-image: url("http://example.com/background.jpg");
or:
@font-face {
font-family: "SiteFont";
src: url("http://cdn.example.com/font.woff2");
}
If the page itself is HTTPS, these references need to be reviewed.
This is especially important after redesigns because a theme or page builder can generate CSS files separately from the main HTML. A website owner may inspect the source code, see HTTPS everywhere, and still receive a mixed-content warning because the insecure URL exists inside a generated stylesheet.
Search CSS files as well as HTML and JavaScript when conducting a complete migration.
What If the Third-Party Resource Has No HTTPS Version?
This is where you need to make a security decision rather than simply edit the URL.
Suppose a website depends on:
http://old-widget.example.com/widget.js
and the provider does not offer HTTPS.
Changing it to:
https://old-widget.example.com/widget.js
will not magically create a secure endpoint.
You have three practical choices:
Replace the service
Find an alternative provider that offers an HTTPS endpoint and supports your required functionality.
Host the resource yourself
This may be appropriate for certain static assets if the licensing permits it, but you then become responsible for maintaining and updating the resource.
Remove the dependency
If the widget is not essential, eliminating it can be safer than keeping an insecure third-party dependency.
Do not preserve an insecure integration simply because it is convenient.
How to Verify That Mixed Content Is Actually Fixed
A website should not be considered fixed simply because the warning disappeared from one browser window.
After making changes, test the page again with DevTools open and inspect the Network panel.
Chrome’s developer tools allow requests to be filtered by scheme and resource characteristics, which makes it possible to verify whether HTTP resources remain.
A thorough verification should cover:
- Homepage
- Important landing pages
- Blog posts
- Forms
- Login and account pages
- Ecommerce and checkout pages
- Search
- API-driven components
- Embedded content
- Mobile layouts
- Pages with older content
Also test pages that were created before the HTTPS migration. These often contain legacy references that newer pages do not.
If users are reporting other HTTPS-related browser problems at the same time, investigate those independently. For example, a Chrome critical error may have an entirely different cause and should not automatically be attributed to mixed content.
A Practical Mixed Content Audit Checklist
Before closing the issue, verify the complete resource chain rather than checking only the page URL.
| Area | What to check |
|---|---|
| Main page | HTTPS loads successfully |
| Certificate | Valid for the requested hostname |
| Images | HTTPS URLs or successfully upgraded resources |
| JavaScript | No HTTP scripts |
| CSS | No HTTP stylesheets or insecure CSS URLs |
| Fonts | HTTPS font resources |
| APIs | HTTPS endpoints |
| Frames | Secure iframe sources |
| CDN | HTTPS asset delivery |
| Plugins | No hard-coded HTTP resources |
| Themes | No insecure asset references |
| Database | Legacy HTTP URLs removed where appropriate |
| Cache | Old HTML and assets purged |
| Dynamic content | AJAX/fetch requests tested |
| Third parties | HTTPS versions available |
| Browser tools | Console and Network panel show no unresolved mixed content |
How to Prevent Mixed Content From Returning
The best solution is not merely to repair today’s warnings. It is to prevent new HTTP references from entering the website.
Developers should use HTTPS URLs when adding new resources, particularly for scripts, stylesheets, APIs, fonts, and third-party integrations. Content teams should also avoid copying old HTTP embed codes into new pages.
For larger websites, include HTTPS validation in deployment and QA processes. A new theme, plugin, CDN migration, application release, or infrastructure change should trigger another security check because any of these changes can introduce insecure resources.
It is also worth reviewing your broader TLS configuration. HTTPS is not only about whether the browser shows a padlock; certificate validity, protocol configuration, private-key handling, certificate chains, and server configuration all contribute to the security of the connection. Understanding the certificate chain of trust is particularly useful when investigating problems that initially look like certificate or browser errors.
Mixed Content Is a Website Configuration Problem, Not Usually a Certificate Problem
The most important thing to remember is that mixed content generally does not mean you need another SSL certificate.
Your certificate can be correctly issued, correctly installed, and fully trusted while the website still requests resources through HTTP.
The actual fix is to identify those resources and move them to HTTPS.
For a small website, that may mean correcting a few image or script URLs. For a WordPress installation, the work may involve database content, plugins, themes, page builders, and caches. For a large application, the source may be a CDN, reverse proxy, API, load balancer, JavaScript application, or dynamically generated resource.
That is why the most reliable troubleshooting process begins with the browser’s actual network requests rather than guessing.
Final Thoughts
Mixed content warnings are a sign that an HTTPS migration is incomplete at the resource level.
The website’s main document may be encrypted, but an HTTP image, stylesheet, JavaScript file, font, API request, iframe, or third-party dependency can create a weaker security boundary. Modern browsers increasingly protect users by upgrading some insecure resources and blocking others, but relying on browser behavior is not a substitute for correcting the website itself.
The most effective approach is to work from evidence: inspect the browser Console, examine Network requests, identify the exact insecure resource, trace its initiator, correct the original URL or configuration, clear caches, and test the affected functionality again.
For developers and administrators, this is also why understanding TLS and SSL in detail matters. HTTPS is not simply an icon displayed by the browser. It is a chain of certificates, cryptographic protocols, server configuration, application behavior, and resource requests that all need to work together.
A properly migrated website should therefore aim for more than a valid certificate. Every resource that contributes to the page should be delivered through a secure connection, and the infrastructure should be configured so that new insecure references do not keep appearing.
That is the difference between simply installing SSL and actually completing an HTTPS migration.
