Fixing Endless Redirect Loops in WordPress with AWS ELB and HTTPS Plugin Configuration


3 views

When deploying WordPress behind an AWS Elastic Load Balancer (ELB), many developers encounter infinite redirect loops when using the WordPress HTTPS plugin. The issue manifests when:

  • ELB terminates SSL (port 443 → port 80)
  • WordPress HTTPS plugin enforces SSL
  • Apache/Nginx rewrites HTTP to HTTPS

Here's what happens in the request cycle:


1. User → HTTPS → ELB (terminates SSL) → HTTP → Server
2. Server sees HTTP (X-Forwarded-Proto: https) 
3. WordPress HTTPS plugin tries to force HTTPS
4. Redirect loop begins

Here's the proper way to configure your stack:

1. Apache Configuration


<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    # ELB Health Check
    RewriteRule ^/health-check$ - [L]

    # Handle HTTPS redirects properly for ELB
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteCond %{REQUEST_URI} !^/health-check
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    
    # Standard WordPress rules
    <Directory /var/www/html>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

2. WordPress HTTPS Plugin Settings

Configure these specific settings:

  • Enable "Proxy" mode in plugin settings
  • Set "SSL Host" to your domain (e.g., example.com)
  • Enable "SSL Proxy" option
  • Disable "Force SSL Admin" temporarily during setup

3. WordPress wp-config.php Tweaks

Add these lines above the "That's all" comment:


// AWS ELB HTTPS Fix
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}
define('FORCE_SSL_ADMIN', true);

Verify with these curl commands:


# Check redirect behavior
curl -I http://example.com

# Verify headers
curl -I -H "X-Forwarded-Proto: https" http://localhost

For those using Nginx instead of Apache:


server {
    listen 80;
    server_name example.com;

    if ($http_x_forwarded_proto != 'https') {
        return 301 https://$host$request_uri;
    }

    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
  • Not enabling "Proxy" mode in WordPress HTTPS plugin
  • Forgetting to update both .htaccess and wp-config.php
  • Having conflicting redirect rules in multiple places
  • Not testing with both HTTP and HTTPS requests

When deploying WordPress behind AWS Elastic Load Balancer (ELB), many developers encounter an endless redirect loop when trying to force HTTPS connections. This occurs due to the interaction between:

  • ELB's header-based protocol forwarding
  • WordPress HTTPS plugins
  • Apache/Nginx rewrite rules

The redirect loop happens because:

1. Browser requests https://example.com
2. ELB forwards to EC2 on port 80 (X-Forwarded-Proto: https)
3. WordPress sees HTTP (not HTTPS) because ELB terminated SSL
4. HTTPS plugin forces redirect to HTTPS
5. Repeat indefinitely

First, verify your ELB listeners:

HTTP 80 → Instance port 80
HTTPS 443 → Instance port 80

Ensure health checks pass by creating a /health endpoint that returns HTTP 200.

Replace your current rewrite rules with this optimized version:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} =http
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

For WordPress HTTPS (SSL) plugin, configure these critical settings:

1. Enable "Proxy" option
2. Set "HTTPS Host" to your domain (e.g., example.com)
3. Ensure "SSL Host Detection" is disabled
4. Whitelist your ELB's IP range

Add this to your wp-config.php before WordPress loads:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 
    $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
}

For those using Nginx instead of Apache:

server {
    listen 80;
    server_name example.com;
    
    if ($http_x_forwarded_proto = "http") {
        return 301 https://$server_name$request_uri;
    }
    
    # Rest of WordPress config...
}

Check these when issues persist:

  1. ELB access logs for request patterns
  2. WordPress siteurl/home values in database
  3. Browser developer tools (Network tab)
  4. Plugin conflicts (temporarily disable all plugins)
  • ✓ ELB properly forwarding X-Forwarded-Proto header
  • ✓ Apache/Nginx correctly interpreting the header
  • ✓ WordPress configured to respect proxy headers
  • ✓ No mixed content in page resources