WordPress is_ssl() doesn’t work behind some load balancers

WordPress has a function is_ssl() that it uses to check whether a page is loaded with the HTTPS protocol, so that it can use the same protocol to load scripts, stylesheets, and other assets. It relies on the web server giving it a couple of clues, but when your website is hosted behind a load balancer, those clues aren’t always available. In particular, websites hosted by Network Solutions get no clues at all when pages are loaded over HTTPS.

Update: SSL Insecure Content Fixer now handles reverse proxies for you. Just pick the appropriate setting for HTTPS detection.

I ran into this recently when someone using my SSL Insecure Content Fixer plugin wasn’t getting any joy, and basic WordPress functions that should have automatically adapted to SSL were all still returning HTTP protocol links. After a brief investigation, it turns out that Network Solutions sites behind load balancers don’t get any clues at all indicating whether a page was loaded over SSL.

Normally, when a page is loaded with the HTTPS protocol, the web server passes a special server variable to tell the website; in PHP it can be checked by looking at $_SERVER['HTTPS']. If that fails, you can check the IP port that the request came in on, to see if it was port 443 (the standard port for SSL); in PHP, you can get that from $_SERVER['SERVER_PORT'].

When your website is behind a load balancer, the load balancer gets that information because that’s what the user’s browser is actually connecting to. It in turn connects to the real web server, but it uses the HTTP protocol, not SSL, so the real web server can’t tell the difference. Amazon’s load balancers apparently provide an extra variable, $_SERVER['HTTP_X_FORWARDED_PROTO'], so you can check for that. If you have some control over the load balancer configuration, you can make it pass some information. But not everyone is so lucky.

To fix the problem on hosts like Network Solutions, you need to trick WordPress into thinking it was passed useful information. It isn’t safe to just assume you’re on SSL, however, so you need to have some idea that you are. The easiest way around this is to put the whole site on SSL by setting the home and site URLs to HTTPS, and then adding the $_SERVER['HTTPS'] variable yourself. Here’s a brief snippet that does that:

// if site is set to run on SSL, then force-enable SSL detection!
if (stripos(get_option('siteurl'), 'https://') === 0) {
    $_SERVER['HTTPS'] = 'on';

Of course, a user can always edit the URL in their browser to put it back to HTTP, so we need another way to ensure that pages end up on HTTPS. This little JavaScript snippet will do that when added to all pages:

if (document.location.protocol != "https:") {
    document.location = document.URL.replace(/^http:/i, "https:");

To save you time and headaches, I’ve put those things together into a simple WordPress plugin. Download this script from gist and save the .php file into the WordPress plugins folder on your website, then activate it in the Plugins admin. It detects when your site’s URL uses HTTPS, and then activates those code snippets above.

Job is done, even on Network Solutions!

  • I would kiss you for this post if i could. I was working on this problem off and on for at least a week. Thank you!!!!!!!!!!!!!!!!

  • [Edit: Ryan has contacted me again and said that this method blocks people from logging in! Please read his second message below, and don’t add this code to your wp-config.php]

    aaahhhhh, man you are amazing.. Thank you so much.. that wordpress-https plugin just hung the site for me and then your plugin didn’t work at first and then I found this post, put

    if (stripos(get_option(‘siteurl’), ‘https://’) === 0) {
    $_SERVER[‘HTTPS’] = ‘on’;

    into my wp-config.php file as I’m running nginx and viola! it works..
    instead of using a js to handle the redirect you can just put this in your httpd.conf or vhost.conf file

    ServerAdmin webmaster@domain
    ServerName domain.com
    ServerAlias *.doman.com
    Redirect permanent / https://domain.com/

    No getting around that, even with scriptblockers on

    • G’day Ryan, good tip about the .htaccess rules. That’ll fix it!


    • paul

      Another note, don’t attempt to put this in your functions.php either, it will also block you from logging into wordpress.

  • Pingback: Fixing ‘This page includes script from unauthenticated sources’ problem with ssl wordpress install on apache+nginx server - Netflow Developments()

  • God, what a nightmare.. So you should probably delete my above post as addin that into the wp-config or wp-settings file causes users to see the good ole You do not have sufficient permissions…. message when logging in. It fixes everything else but you are no longer able to access your admin area. Installing the little plugin you made here however fixes it completely

    • No worries, Ryan. I’ve edited your comment above so that it can be read as a “what not to do” :)


  • Ed Roms

    Will this plugin be required in future versions of WordPress? If so, how long will it be before a fix for the problem is put into WordPress core? BTW, thanks much for sharing this excellent work.

    • G’day Ed,

      I doubt that WordPress will build this into the core because the exact problem is very specific to the hosting environment in which you run WordPress. This is a kludge that gets your site working, but it has its drawbacks — for example, someone visiting your site with JavaScript disabled can edit the URL in their browser to visit a page without SSL, and your site will just assume they’re using SSL. That’s unlikely to happen, and it won’t really have an impact on most websites but might be important for some sites.

      Some hosting environments support HTTP_X_FORWARDED_PROTO which WordPress could feasibly check for as well in its is_ssl(), but even that is problematic: it’s a simple HTTP header that can easily be forged, thus fooling a site into thinking it’s delivering SSL, so it can only really be relied upon in specific environments.

      So no, this isn’t something that WordPress can easily put into core, unfortunately.


  • Jessie

    Thank you SO much!

    I have been banging my head getting constant “redirect loop” errors. I’ve tried EVERY .htaccess method, wordpress ssl plugin, wordpress https plugin and STILL couldn’t figure it out. I am SO glad that it’s actually a Network Solutions error because I was starting to feel crazy!

    This worked wonders! You saved me! Thanks so much!!

  • henry

    Thank you so much!
    This code combined the 2 solutions I spent so long looking for; and was trying unsuccessfully to merge!!!

    Although I am now running into issues with the Advanced Custom Field plugin. It still wants to pull in content (css, js) using HTTP. I checked other forums and blogs and the plugin was patched months ago to use get_content_url() and get_plugin_url() so that it wouldnt have this problem. However I am still having this very issue.

    Any light any one could shed on this conflict would be greatly appreciated ;)

  • Alvin

    Help! This solution isn’t working for me!! Has this stopped working with newer versions of wordpress?

    I’ve tried these plugins with no success: Force SSL URL Scheme, SSL Insecure Content Fixer, WordPress HTTPS. Still my site is displaying without most scripts and stylesheets!

    Network Solutions support doesn’t have a clue! I’m losing years of my life stressing out over this!!

    Any help would be very greatly appreciated.

    • G’day Alvin, have you installed and activated Force SSL URL Scheme and then changed your Home (WordPress Address) URL and Site URL to both use https? If you don’t change your home and site URLs to https, Force SSL URL Scheme won’t do anything.

      Yes, I have confirmed the script still works with WP 3.8.


      • Alvin

        Thanks so much for your reply!

        I’m actually looking to only secure individual pages on the site, not the whole site. Was trying to use the ‘WordPress HTTPS’ plugin for that, but it isn’t working. Is there an alternate method?

        I did try your solution temporarily just to see if it would work site-wide. It’s much better, but not everything is there, and I’m still getting the “unauthenticated sources” message. Any clues?

        • G’day Alvin,

          This is my blog, I suggest you post a full description of your problem complete with a link to your site over at the support forum for my SSL Insecure Content Fixer plugin.


  • Paul Sipos

    Many thanks Ross,

    I use your plugin on a website behind a Zeus appliance Load Balancer.
    The Load Balancer is not yet configured to set the HTTPS or the X_FORWARDED_PROTO environment variables so I had to trick the is_ssl() function by setting the HTTPS variable to on in vhosts.conf in apache

    SetEnv HTTPS “on”

    I tested the wp-admin interface and other sections of the website using the wp-login.php and all seems to work just fine with define(‘FORCE_SSL_LOGIN’, true); in wp-config.php

    I hope my experience helps others take advantage of your great plugin.


  • Lifesaver! I had the same issue with 123-reg in the UK, works a treat.

    • Hi Chirs, how did you implement out of interest?

      Ive got a client using 123 Reg and only want ssl on checkout in woocommerce.

      • Oriche’

        Hi Mathew,

        I have the same problem as your client. I am also with 123 reg and have woo commerce. And just want the checkout with SSL but the style sheets will not load under ssl. Did you manage to get the answer?

        Kind Regards,


        • My clients was fine, I would assume that your style sheet had a full url reference for your domain which would have http: and not https: or something similar. SImply change the source code to the relative url for the stylesheet, eg: /wp-contet/css/yourstylesheet.css or what ever it may be, you should be able to work it out from viewinfg your page source and then editing your themes header.php file… again all dependant on the theme being used.

    • Oriche’

      Hi Chris,

      I am also with 123-reg UK and my SSL works but it wrecks the appearance of the website.
      Any info you have on this problem and the script I would really appreciate if
      you can tell me?

      Kind Regards,


  • GOStickITdotBiz

    Any help please? I have an SSL working only on the CHECKOUT page but clearly there is a FONT issue. http://vape20.com only if you get to the checkout page though it happens across the top! Thanks!

  • Hey thanks for this! Works great when working with WP and cloudflare.

  • Gary

    Thanks so much Ross. I spent hours trying to figure this out then found this Post/plugin. Works perfectly – much appreciated.

  • Yes!! That plugin is work perfectly for me.. :D
    I spent 2 days trying to solve this problem, but I can’t get fix. And then my issue was solved. Thanks so much..

  • Hi All, could you please help me with my theme? I put the plugin in my theme https://www.seoshark.us and is not working? Is something wrong with my theme?

  • Lol why would you use JS to forward…. NEVER SEC-ROUTE WITH JS. So easy to bypass…..most automation doesnt even run JS. Instead, just set header (301) and (Location) then exit() at PHP level.

    • If you’re using this snippet, it’s because you can’t tell whether you’re on HTTP or HTTPS from PHP, thus your suggestion would lead to an endless loop of redirects. Best is to redirect from .htaccess or NginX config, but again you’d only be using this snippet if you cannot detect which protocol the visitor is using, because a reverse proxy of some sort is masking that. LOL :)

      • Yes, you have to detect one of the 10 common headers and spoof it as HTTPS ‘on’. If a host does not include one of these (or even no header at all like network tools), they are amateurs and should be totally avoided since they are not viable to run a production site.

        But really, the fact that you forward with JS is a major flaw. Why dont you just set 301 headers in PHP using the same logic?

        • Think about what you just said. If you set 301 headers in PHP, and can’t detect HTTP/HTTPS, you’ll be setting up an endless loop of redirects. Either deal with it safely with .htaccess or NginX config if you can (which isn’t the scenario here), or dig yourself out at the browser side with JS.

          The JS isn’t to prevent access via HTTP, it’s only about sending ordinary users (with JS enabled) back to a secure page. The whole thing is a hack, designed to help people live with their poor choice of host (e.g. Network Solutions) until they can move.

          That horse you’re on seems too high for you, maybe you should get down off it now.

  • Roth

    Thanks, it helped us a lot, it’s working with AWS ELB.

  • Does anyone know if this issue with network solutions has been cleared up or do I have to use this script. FYI – I already use a plugin in wordpress that forces http to https sitewide. If NS has not worked this out (or wordpress?) Am I good to go considering I already am forcing the entire domain?

  • I installed the plugin but it didn’t fix the error I’m seeing. Here is the checkout page > https://my.rebootedbody.com/checkout/?rid=pj2z89 — it’s throwing a error on WhyNoPadlock. Can you tell me if you see anything obvious here?

    • G’day Kevin, I can’t see your site at present (no response) but as it says in the manual forms are not fixed by the plugin at present because fixing them could hide bigger problems. You should find out what the form is, and make sure that its target supports https: before changing it. If you need to discuss this further, please open a topic in the support forum.

  • Robert Harte

    I want to share my experience, maybe it will help someone. I’m not a developer, but an amateur. Probably my fix isn’t correctly executed, but it works.

    My website goes fully via https. After installing WordPress I was completely blocked out of the admin. Installing a plugin wasn’t even possible. I found the force ssl-url-scheme.php which worked great. But after upgrading to WP 4.3 my website went completely white again.

    I solved the problem as follows:
    Step 1: made a file with the name force-ssl.php in the wp-includes folder and added the following script:
    if (stripos(get_option('siteurl'), 'https://&#039;) === 0) {
    $_SERVER['HTTPS'] = 'on';

    Step 2: the script must be loaded to become effective. This can be done in the wp-settings.php file.

    Scrolled to the line:
    // Load most of WordPress.
    111 require( ABSPATH . WPINC . '/formatting.php' );
    112 require( ABSPATH . WPINC . '/capabilities.php' );
    And I added the following line:
    require( ABSPATH . WPINC . '/force-ssl.php' );


  • Osman Kale


  • Great, works fine. Thank you!

  • Ademola Alabi

    Works So Well, Thank You