HTTP to HTTPS Redirects: The Complete Guide
Complete guide to migrating from HTTP to HTTPS: server configuration, redirect implementation, mixed content issues, HSTS, and SEO considerations for a smooth transition.
Migrating from HTTP to HTTPS is one of the most common redirect operations, and one of the easiest to get wrong. A correct implementation is a single 301 redirect per URL. A botched implementation creates redirect loops, mixed content warnings, SEO ranking drops, and broken functionality.
This guide covers every step: server configuration, redirect rules, mixed content resolution, HSTS deployment, and SEO verification. For the full overview of all redirect types, see our HTTP Redirect Guide.
Why HTTPS matters
HTTPS is no longer optional. It is a baseline requirement for any website. [1]
Security
SEO ranking signal
Browser trust
Required for modern APIs
HTTP/2 and HTTP/3
Before starting the migration, make sure you have a valid SSL certificate installed for your domain and all subdomains. If you need a free certificate, Let's Encrypt is the standard choice.
The redirect architecture
The correct HTTP to HTTPS redirect is a 301 from every HTTP URL to its HTTPS equivalent:
http://example.com/any-page
--> 301 --> https://example.com/any-page
http://www.example.com/any-page
--> 301 --> https://www.example.com/any-page
The redirect should preserve the full path and query string. It should not redirect to the homepage or strip URL parameters.
CORRECT:
http://example.com/products?category=shoes&sort=price
--> https://example.com/products?category=shoes&sort=price
WRONG:
http://example.com/products?category=shoes&sort=price
--> https://example.com/ (path and query lost)
--> https://example.com/products (query string lost)
If you are also consolidating www and non-www, do both in a single hop. Do not create a redirect chain where HTTP redirects to HTTPS, which then redirects non-www to www (or vice versa). Combine them.
Server configuration
Nginx
# Redirect all HTTP traffic to HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS server block
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# ... your site configuration
}
Use return, not rewrite
In Nginx, return 301 is faster than rewrite ... permanent because it does not require regex processing. For a simple HTTP-to-HTTPS redirect, always use return. For more Nginx redirect patterns, see Nginx Redirect Configuration Guide.
Apache
# In .htaccess or VirtualHost config
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
For more on .htaccess syntax and common patterns, see .htaccess Redirect Rules Guide.
Apache (alternative with mod_alias)
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
IIS (web.config)
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
For more on IIS redirect rules, see IIS URL Redirect Guide.
CDN-level redirects
Most CDNs offer HTTPS enforcement at the edge, which is the fastest option:
| CDN | Setting | Location |
|---|---|---|
| Cloudflare | Always Use HTTPS | SSL/TLS > Edge Certificates |
| AWS CloudFront | Viewer Protocol Policy: Redirect HTTP to HTTPS | Distribution > Behaviors |
| Fastly | Force TLS and HSTS | Configuration > Settings |
| Vercel | Automatic (enabled by default) | No configuration needed |
| Netlify | Automatic (enabled by default) | Domain settings > HTTPS |
For a detailed walkthrough of Cloudflare redirect configuration, see Cloudflare Redirect Guide.
Trace your redirect chains
Find redirect loops, broken chains, and unnecessary hops instantly.
Avoiding redirect loops
The most common HTTP-to-HTTPS redirect problem is a loop. It happens when your application or origin server does not know the request originally arrived over HTTPS because a load balancer or CDN terminated the SSL connection.
User (HTTPS) --> CDN/LB (terminates SSL) --> Origin (sees HTTP)
Origin: "This is HTTP, redirect to HTTPS"
CDN/LB: follows redirect, terminates SSL again
Origin: "This is still HTTP, redirect to HTTPS"
... (loop)
If you are seeing this error, see How to Fix ERR_TOO_MANY_REDIRECTS for a step-by-step diagnosis.
The fix: trust X-Forwarded-Proto
When a load balancer terminates SSL, it adds an X-Forwarded-Proto: https header. Your redirect rule should check this header:
# Nginx behind a load balancer
server {
listen 80;
# Only redirect if the original request was HTTP
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
}
# Apache behind a load balancer
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Do not redirect at multiple layers
Configure the HTTP-to-HTTPS redirect at exactly one layer: either the CDN, the load balancer, or the web server. Never at more than one. Multiple redirect layers working independently is the most common cause of HTTPS redirect loops.
Mixed content: the hidden problem
After enabling HTTPS, your pages may still load resources (images, scripts, stylesheets, fonts) over HTTP. Browsers block or warn about this "mixed content." [2]
Types of mixed content
| Type | Examples | Browser Behavior |
|---|---|---|
| Active (blocked) | Scripts, stylesheets, iframes, fetch/XHR | Blocked entirely, page may break |
| Passive (warning) | Images, video, audio | Loaded with warning in console |
Finding mixed content
Check your browser's DevTools console for mixed content warnings:
Mixed Content: The page at 'https://example.com/page' was loaded over HTTPS,
but requested an insecure image 'http://example.com/image.jpg'.
Fixing mixed content
Update internal references to HTTPS
Change http://example.com/image.jpg to https://example.com/image.jpg. Protocol-relative URLs (//example.com/image.jpg) also work but explicit HTTPS is clearer.
Update hardcoded HTTP URLs in your database
For CMS sites, run a search-and-replace on your database to update http://yourdomain.com to https://yourdomain.com.
Update third-party resource URLs
Ensure all external scripts, stylesheets, and images use HTTPS. Most third-party services support HTTPS.
Add Content-Security-Policy header
Use upgrade-insecure-requests to automatically upgrade HTTP requests to HTTPS:
Content-Security-Policy: upgrade-insecure-requests
HSTS: making HTTPS permanent
HTTP Strict Transport Security (HSTS) tells browsers to always use HTTPS for your domain, even if the user types http://. This eliminates the initial HTTP request entirely after the first visit. [3]
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
HSTS deployment strategy
Deploy HSTS gradually to avoid locking yourself out:
Start with a short max-age
Set max-age=300 (5 minutes). If something breaks, it only lasts 5 minutes.
Increase gradually
After confirming everything works, increase to max-age=86400 (1 day), then max-age=604800 (1 week).
Set final max-age
Once confident, set max-age=31536000 (1 year) and add includeSubDomains.
Submit to HSTS preload list (optional)
Add the preload directive and submit your domain to hstspreload.org. This hardcodes HTTPS enforcement into browsers. Be absolutely certain before doing this, as removal takes months.
HSTS preload is hard to undo
Once your domain is on the HSTS preload list, every Chrome, Firefox, Safari, and Edge user will be forced to use HTTPS. Removing your domain from the list takes months and requires a browser update to take effect. Only preload after you are 100% committed to HTTPS on all subdomains.
SEO checklist for HTTP to HTTPS
After implementing the redirect, verify these SEO elements:
- Google Search Console: Add the HTTPS property and verify ownership. The HTTP and HTTPS versions are separate properties.
- Sitemap: Update your sitemap to use HTTPS URLs. Submit the updated sitemap in Search Console.
- Canonical tags: Ensure all
<link rel="canonical">tags use HTTPS URLs. - Internal links: Update all internal links from HTTP to HTTPS. While the redirect handles them, direct HTTPS links are faster and avoid redirect hops.
- Robots.txt: Ensure the HTTPS version of robots.txt is accessible and correct.
- Structured data: Update any absolute URLs in your JSON-LD or schema markup to HTTPS.
- Social meta tags: Update Open Graph and Twitter Card URLs to HTTPS.
- DNS records: Verify your DNS configuration points to the correct servers for HTTPS.
Verification
After deployment, verify the complete redirect chain:
# Check the redirect
curl -I http://example.com/
# Should show: HTTP/1.1 301 Moved Permanently
# Location: https://example.com/
# Check HSTS header
curl -I https://example.com/
# Should show: Strict-Transport-Security: max-age=31536000; ...
# Check for mixed content (download page and search for http://)
curl -s https://example.com/ | grep -c "http://"
# Should be 0 (or only in safe contexts like links to external sites)
For a full site audit, use How to Check Redirects in Bulk to verify every URL has correct HTTPS enforcement. For ongoing monitoring of your SSL certificates after migration, use SSL Certificate Expiry to get alerts before your certificate expires and breaks the HTTPS you just set up.
References
- Google, "HTTPS as a ranking signal," Google Search Central Blog, August 2014. https://developers.google.com/search/blog/2014/08/https-as-ranking-signal
- MDN Web Docs, "Mixed content," Mozilla, 2024. https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
- IETF, "RFC 6797 - HTTP Strict Transport Security (HSTS)," November 2012. https://datatracker.ietf.org/doc/html/rfc6797
Never miss a broken redirect
Trace redirect chains and detect issues before they affect your users and SEO. Free instant tracing.
Try Redirect Tracer