HTTPS Redirect Guide: How to Force HTTPS on Any Server
Force HTTPS on Apache, Nginx, Cloudflare, and WordPress. Avoid mixed content errors, redirect loops, and common HTTPS migration pitfalls.
Last updated: 2026-02-17
Why HTTPS Is Non-Negotiable
HTTPS is not optional. Browsers mark HTTP sites as "Not Secure." Google uses HTTPS as a ranking signal. Users see the padlock icon and trust your site. Without HTTPS, you lose rankings, trust, and conversions.
But enabling HTTPS is only half the job. You also need to redirect all HTTP traffic to HTTPS so that every visitor, every crawler, and every inbound link reaches the secure version of your site. A missing or misconfigured HTTPS redirect means some users still hit the insecure version, search engines index both versions, and your link equity splits between HTTP and HTTPS URLs.
This guide covers how to implement HTTPS redirects correctly on every major platform, and how to avoid the pitfalls that cause redirect loops, mixed content warnings, and SEO problems.
Before You Start: Prerequisites
Get a Valid SSL Certificate
Test the Certificate
https://yourdomain.com directly. It should load without any browser warnings. If it does not, fix the certificate installation before adding any redirects.Inventory All Domains and Subdomains
example.com, www.example.com, blog.example.com, etc. Each one needs HTTPS configured and redirected.Identify Your Server Stack
HTTPS Redirects on Apache
Apache uses .htaccess files or the main server configuration for redirect rules.
Basic HTTP to HTTPS Redirect
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This checks if the connection is not HTTPS (%{HTTPS} off), and if so, redirects to the same URL with https://. The R=301 flag makes it a permanent redirect. The L flag stops processing further rules.
Combined www and HTTPS Redirect (Single Hop)
If you also want to redirect www to non-www (or vice versa), combine both into one rule to avoid a redirect chain:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]
This handles all four variations (http://www, http://non-www, https://www, http://non-www) in a single redirect to https://example.com.
Always combine your www/non-www redirect with your HTTPS redirect into a single rule. Two separate rules create a redirect chain where the browser makes two requests instead of one.
Apache Behind a Load Balancer or Proxy
If your Apache server is behind a load balancer that terminates SSL, the %{HTTPS} variable will always be "off" because the connection from the load balancer to Apache is HTTP. Use the X-Forwarded-Proto header instead:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
HTTPS Redirects on Nginx
Nginx handles redirects in server blocks within the configuration file.
Basic HTTP to HTTPS Redirect
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
This creates a separate server block that listens on port 80 (HTTP) and redirects everything to HTTPS. Using return 301 is more efficient than using rewrite in Nginx.
Combined www and HTTPS Redirect
# Redirect www (both HTTP and HTTPS) to non-www HTTPS
server {
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
return 301 https://example.com$request_uri;
}
# Redirect HTTP non-www to HTTPS non-www
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
# Main HTTPS server block
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Your site configuration here
}
Nginx Behind a Proxy
server {
listen 80;
server_name example.com;
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
# Normal configuration
}
Monitor your HTTPS configuration continuously
Site Watcher checks SSL certificates, redirect chains, and HTTPS enforcement for all your targets. Catch misconfigurations before they affect visitors.
HTTPS Redirects with Cloudflare
Cloudflare sits between your visitors and your origin server, which adds a layer of complexity to HTTPS redirects.
Enable HTTPS Redirect in Cloudflare
- Log into the Cloudflare dashboard
- Select your domain
- Go to SSL/TLS > Edge Certificates
- Enable Always Use HTTPS
This tells Cloudflare to redirect all HTTP requests to HTTPS at the edge, before they even reach your server.
Set the Correct SSL Mode
This is critical and is the most common source of redirect loops with Cloudflare.
| SSL Mode | Connection to Origin | When to Use | Redirect Loop Risk |
|---|---|---|---|
| Off | HTTP only | Never (insecure) | No redirects from Cloudflare |
| Flexible | HTTP (even if visitor uses HTTPS) | Origin has no SSL certificate | HIGH if origin also forces HTTPS |
| Full | HTTPS (accepts self-signed) | Origin has self-signed cert | Low |
| Full (Strict) | HTTPS (requires valid cert) | Origin has valid CA-signed cert | None |
If your origin server has a valid SSL certificate and its own HTTPS redirect, you MUST use "Full" or "Full (Strict)" mode in Cloudflare. "Flexible" mode will create a redirect loop because Cloudflare connects to your origin over HTTP, your origin redirects to HTTPS, Cloudflare receives the redirect and forwards it to the visitor, who requests HTTPS, which Cloudflare sends to the origin over HTTP again, creating an infinite loop.
Remove Server-Level HTTPS Redirects (Optional)
Once Cloudflare's "Always Use HTTPS" is enabled, you can optionally remove the HTTPS redirect from your origin server. Cloudflare handles it at the edge, which is faster. However, keeping the origin redirect as a safety net is also valid in case Cloudflare is ever bypassed or disabled.
HTTPS Redirects in WordPress
WordPress has its own URL settings that interact with server-level redirects.
Step 1: Update WordPress URLs
- Go to Settings > General
- Change both WordPress Address (URL) and Site Address (URL) to use
https:// - Save
If you cannot access the admin panel (because of a redirect loop), edit wp-config.php:
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');
Step 2: Add the Server-Level Redirect
Even after updating WordPress URLs, you still need a server-level redirect to handle direct HTTP requests. Use the Apache or Nginx rules above.
Step 3: Fix Internal Links
After switching to HTTPS, internal links and embedded resources may still reference HTTP URLs. Use a search-and-replace tool (like Better Search Replace plugin) to update all instances of http://example.com to https://example.com in the database.
WordPress Behind a Reverse Proxy
If WordPress is behind Cloudflare, a load balancer, or any proxy that terminates SSL, add this to wp-config.php:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
Without this, WordPress thinks every request is HTTP (because the proxy-to-server connection is HTTP) and creates a redirect loop.
Common HTTPS Migration Pitfalls
Mixed Content Warnings
After switching to HTTPS, if your pages still load resources (images, scripts, stylesheets, fonts) over HTTP, browsers will show a mixed content warning or block those resources entirely.
How to find mixed content:
- Check the browser console for mixed content warnings
- Use a crawler to scan all pages for HTTP resource references
- Search your database and template files for
http://references to your own domain
How to fix it:
- Update all internal resource URLs to HTTPS or use protocol-relative URLs (
//example.com/image.png) - Run a database search-and-replace for your domain from
http://tohttps:// - Check hardcoded URLs in theme files, widgets, and custom code
Redirect Loops
The most common HTTPS pitfall. Causes include:
- Cloudflare "Flexible SSL" combined with server-level HTTPS redirect
- WordPress
WP_HOME/WP_SITEURLset to HTTP while a redirect forces HTTPS - Both a CDN and the origin server enforcing HTTPS redirects that conflict
- A caching plugin serving a cached redirect response
See the fix-err-too-many-redirects guide for detailed solutions to each of these scenarios.
Forgetting Subdomains
Your main domain may be on HTTPS, but what about blog.example.com, shop.example.com, cdn.example.com, and mail.example.com? Each subdomain needs its own SSL certificate (or a wildcard certificate) and its own HTTPS redirect.
Not Updating External References
After migrating to HTTPS, update your URL everywhere it appears externally:
- Google Search Console (add the HTTPS property)
- Google Business Profile
- Social media profiles
- Email signatures
- Third-party directory listings
- API integrations that use your URL
HSTS (HTTP Strict Transport Security)
After confirming HTTPS works correctly, add an HSTS header to tell browsers to always use HTTPS for your domain. This eliminates the initial HTTP request entirely for returning visitors.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Start with a short max-age (like 300 seconds) and increase it gradually. HSTS is hard to undo once browsers have cached the header. If you have a misconfiguration, a long max-age means visitors cannot access your site over HTTP as a fallback.
Monitoring HTTPS Status
HTTPS is not a one-time setup. Certificates expire, configurations change, and dependencies can introduce mixed content. Ongoing monitoring catches problems before they reach visitors.
SSL Certificate Expiry Monitoring
HTTPS Enforcement Verification
Certificate Chain Validation
Redirect Chain Detection
Mixed Content Scanning
HTTPS Redirect Verification Checklist
After implementing your HTTPS redirect, verify all of these:
| Test | Expected Result | Tool |
|---|---|---|
| http://example.com | 301 redirect to https://example.com | curl -I |
| http://www.example.com | 301 redirect to https://example.com | curl -I |
| https://www.example.com | 301 redirect to https://example.com | curl -I |
| https://example.com | 200 OK (no redirect) | curl -I |
| SSL certificate valid | Valid, correct domain, full chain | SSL checker tool |
| No mixed content | No HTTP resources loaded | Browser console |
| HSTS header present | Strict-Transport-Security header in response | curl -I |
A correct HTTPS redirect is a single 301 hop from HTTP to HTTPS that works for every domain variation, does not create loops with your CDN or proxy, and covers every subdomain serving your content.
Monitor SSL and HTTPS Across All Your Sites
Site Watcher tracks SSL certificate expiry, HTTPS enforcement, redirect chains, and certificate configuration for every target. $39/mo unlimited, free for 3 targets.