Why does my browser say my SSL page is only “partially secure” or contains “mixed content”?

This page is showing a generic answer.
To see a more detailed answer customized for you, type your domain name here:

The first step to making your pages display as “secure” is adding a free SSL certificate, then accessing your site using https:// at the beginning (with an extra “s”). (We have an overview page explaining how to get started with SSL.)

If your SSL web page includes non-secure images, CSS files or JavaScript — that is, if your “https” page in turn includes URLs beginning with http:// instead of https:// — the page still won’t show as fully secure, though.

Each Web browser handles this situation differently. Some browsers may ask if you want to display the nonsecure items, for example. Others may tell you that that the page is only “partially secure”, or is “not fully secure” or “contains mixed content”. In many cases, the “padlock icon” in the browser may not fully activate, or the word “Secure” may not appear in the address bar. The Google Chrome browser displays it like this:

SSL Warning icon

Firefox displays it like this:

Firefox insecure icon

To prevent this from happening, make sure that none of the page’s included URLs begin with http://, such as src="http://. You can replace such URLs with src="https://, or use URLs that don’t include any hostname.

On this page:

Fixing this in WordPress

If your site is a WordPress site, you can often fix this by logging in to the WordPress dashboard, clicking Settings > General, and changing both the “WordPress Address (URL)” and “Site Address (URL)” so that they begin with https:// (that is, add an s after “http” and before the colon). This will force WordPress to use your SSL certificate for most resources it tries to load.

If that doesn’t completely fix it, it’s probably because the site has other hard-coded non-https URLs in the database somewhere. We can help you fix this; just contact us and ask for help making the site fully secure.

When we do that, we’ll use the command-line shell, running these wp-cli commands to replace every occurrence of a non-SSL URL with the SSL version:

wp search-replace example.com.customers.tigertech.net example.com --all-tables-with-prefix --report-changed-only
wp search-replace http://example.com https://example.com --all-tables-with-prefix --report-changed-only
wp search-replace http://www.example.com https://www.example.com --all-tables-with-prefix --report-changed-only
wp search-replace 'http:\/\/example.com' 'https:\/\/www.example.com' --all-tables-with-prefix --report-changed-only
wp search-replace 'http:\/\/www.example.com' 'https:\/\/www.example.com' --all-tables-with-prefix --report-changed-only
rm -rf wp-content/cache/*

(The last line intentionally includes a * on the end to avoid deleting any “.htaccess” file in the cache directory.)

If you’re a technically advanced user comfortable with the shell, you’re welcome to do this yourself instead.

Finally, clear your web browser’s cache to test that your site is fully secure.

If that all works, it’s probably a good idea to redirect non-SSL requests to SSL (we’ll do this for you if you ask us to fix it).

If you still have trouble, or if you don’t use WordPress, you’ll have to track down the exact problem using the tips below.

An example of the problem

Let’s say your page is at this “https” address:

https://www.example.com/

... and that page’s HTML source code includes a CSS file, an image file, and a JavaScript file that use “http” addresses:

<link rel="stylesheet" href="http://www.example.com/style.css">

<img src="http://www.example.com/image.jpeg">

<script src="http://www.third-party-site.com/script.js">

This won’t work properly, because the visitor’s Web browser will load the HTML part of the page using “https”, but will then load the CSS, image and JavaScript files over “http”, without SSL. That’s what “partially insecure” or “partially secure” means.

To fix this for items included from your own site, you can remove the hostname from the URLs. That way, the visitor’s browser will automatically use SSL to load the included items when the enclosing page is loaded as SSL:

<link rel="stylesheet" href="/style.css">

<img src="/image.jpeg">

But that trick won’t work if your HTML code references content on a third-party site: you’d need to change that one to something like:

<script src="https://www.third-party-site.com/script.js">

This will only work if the third-party site allows SSL, though. If they don’t, there's no way to fix it.

In a pinch, some people just force all included URLs to always be loaded as SSL, although this will slow down your site for visitors who don’t load the enclosing page as SSL:

<link rel="stylesheet" href="https://www.example.com/style.css">

<img src="https://www.example.com/image.jpeg">

<script src="https://www.third-party-site.com/script.js">

Finding the problem in detail

The easiest way to find exactly what’s wrong with a given page is usually to use the third-party Why No Padlock? site. It can often (but not always) tell you exactly what’s wrong.

If that doesn’t work or you want more details, many web browsers will show you the source of the problem if you view the page in question, then open a special window:

  • In Google Chrome, choose More Tools > Developer Tools, then look at the “Console” tab
  • In Mozilla Firefox, choose Tools > Web Developer > Web Console, then reload the page
  • In Safari, enable the Develop menu and choose Show Error Console

These windows will usually tell you something like “The page at https://www.example.com/ ran insecure content from http://www.example.com/style.css”, or “The page at https://www.example.com/ was loaded over HTTPS, but requested an insecure script from https://www.third-party-site.com/script.js”.

Using the Content-Security-Policy “upgrade-insecure-requests” header

If all else fails, there’s one other option: You can make your site send a special “header” that tells browsers to try to convert all non-SSL requests to SSL for anything it loads from the current page.

This usually works, but some older browsers don’t support it, so the main potential drawback is that a site might show as “secure” in new browsers and “not secure” in older ones. In addition, if the converted URL can’t be loaded using SSL, it will simply be ignored. To avoid these drawbacks, it’s better to fix URLs properly (as described above) if you can.

To use this header on your site, you can add a “Redirect non-SSL requests to SSL” redirect in our control panel, which adds the header to HTTP responses on your site as a side-effect.

Alternately, you can manually add this single line to your site’s .htaccess file:

Header set Content-Security-Policy upgrade-insecure-requests;