Troubleshooting SSL Mixed Content Warnings on HTTPS Pages
A mixed content warning occurs when a secure HTTPS page attempts to load subresources—such as images, scripts, stylesheets, or iframes—over an insecure HTTP connection. Modern browsers flag these pages to protect users from man-in-the-middle attacks, which can break your site layout, disrupt functionality, and hurt user trust. Fixing these insecure elements requires scanning your web application, updating resource links, and enforcing strict security headers.
Before you start making sweeping changes to your codebase, you need to understand what technologies and frameworks your site relies on. You can use the Website Technology Checker to quickly analyze your live domain stack, identify content management systems, plugins, or third-party widgets, and pinpoint where legacy scripts might be hiding.
Understanding Mixed Content Types
Browsers divide mixed content into two primary categories based on the security risk they pose to the end-user. Knowing the difference helps you prioritize which fixes to implement first.
Mixed Passive (Display) Content
Mixed passive content includes images, audio, and video files loaded over HTTP within an HTTPS page. While an attacker cannot directly alter the core page layout, they can swap out these assets to alter user perception or track visitor behavior. Browsers generally allow mixed passive content to load but often display a warning icon in the address bar.
Mixed Active Content
Mixed active content includes scripts, stylesheets, iframes, WebSockets, and other executable code loaded over HTTP. This category poses a severe security risk because an attacker can intercept the insecure resource and execute arbitrary JavaScript, steal session cookies, or completely hijack the user session. Browsers block mixed active content entirely, resulting in broken layouts and dysfunctional site features.
Step-by-Step Troubleshooting Process
Resolving mixed content issues systematically ensures you do not miss hidden elements buried deep within database entries or third-party configurations.
Step 1: Identify the Broken Resources
Open your website in a modern browser, navigate to the page showing the warning, and open the Developer Tools console (F12 or Ctrl+Shift+I on Windows, Cmd+Option+I on macOS). Look at the Console and Security tabs. The browser will explicitly list every insecure resource URL causing the warning, along with the line number or file that called it.
Step 2: Search Your Source Code and Database
Once you have the list of insecure URLs, locate where they originate in your project files or content management system database.
For a static HTML site, search your repository using command-line tools:
grep -rn "http://example.com/assets/" .
For dynamic database-driven platforms, run a targeted SQL query to find hardcoded HTTP references in posts, pages, or options tables:
SELECT * FROM wp_posts WHERE post_content LIKE '%http://example.com/%';
Step 3: Update Resource URLs to HTTPS
Replace all instances of http:// with relative URLs (e.g., //example.com/image.jpg) or explicit https:// links. Using protocol-relative URLs allows the browser to automatically request the asset using whichever protocol loaded the parent page.
| Approach | Syntax Example | Best Use Case |
|---|---|---|
| Absolute HTTPS | https://example.com/css/style.css |
External domains, CDNs, and API endpoints |
| Protocol-Relative | //example.com/js/script.js |
Internal assets shared across HTTP and HTTPS |
| Absolute HTTP | http://192.0.2.1/image.png |
Never use on production HTTPS sites |
Step 4: Implement Content Security Policy (CSP)
To catch remaining legacy references automatically and prevent future regressions, deploy the Content-Security-Policy header. You can use the upgrade-insecure-requests directive to instruct the browser to treat all HTTP subresource requests as HTTPS.
Add this HTTP header to your web server configuration (such as Nginx or Apache):
Content-Security-Policy: upgrade-insecure-requests;
For Nginx, add the following line inside your server block:
add_header Content-Security-Policy "upgrade-insecure-requests;" always;
For Apache, add this line to your .htaccess file:
Header always set Content-Security-Policy "upgrade-insecure-requests;"
Verification and Testing
After updating your code and headers, verify that your changes took effect properly.
Use curl to check if your headers are returning correctly and if your assets redirect properly:
curl -I https://example.com
Sample expected output:
HTTP/2 200
server: nginx
content-security-policy: upgrade-insecure-requests;
strict-transport-security: max-age=31536000
You can also use automated command-line scanners or online tools to crawl your site and verify zero HTTP references remain in your HTML, CSS, and JS files.
Common Mistakes and How to Fix Them
Even experienced developers run into roadblocks when cleaning up mixed content. Avoid these frequent pitfalls:
- Hardcoded URLs in Plugins or Themes: Many third-party templates store static asset paths in configuration files or database serialization strings. If a simple search-and-replace fails, use a serialized search-and-replace script designed for your specific CMS.
- Forgetting CDN and External Embeds: Widgets, social media buttons, and external analytics scripts often load over HTTP by default. Contact the provider for their HTTPS embed code or replace the script.
- Ignoring CSS Background Images: URLs defined inside CSS files (like
background-image: url('http://example.com/bg.jpg')) do not always trigger console warnings in the same way script tags do, but they still compromise your HTTPS security posture.
Quick Checklist for Mixed Content Resolution
- Open browser developer console and note all insecure URLs.
- Scan source code and database tables for hardcoded
http://links. - Update resource paths to use absolute
https://or protocol-relative//formats. - Configure the
upgrade-insecure-requestsContent-Security-Policy header. - Test the live pages across multiple modern browsers to confirm zero warnings.
- Set up continuous monitoring to catch newly added insecure assets.