To force HTTPS in Apache with .htaccess, add a RewriteRule that catches all HTTP requests and permanently redirects them (301) to their HTTPS equivalent. It's the fastest way to enable the redirect without editing Apache's main configuration files.
Below you'll find the exact rule, variants for special environments, and the most common mistakes that cause redirects to fail or trigger infinite loops.
The Basic Rule: HTTP → HTTPS in .htaccess
Open (or create) the .htaccess file in your site's root directory and add the following:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Those three lines are enough for most Apache servers with SSL active. Here's what each part does:
- RewriteEngine On — activates the rewrite engine. Nothing works without this.
- RewriteCond %{HTTPS} off — only applies the rule when the connection is not HTTPS.
- RewriteRule ^(.*)$ — captures the full URL and redirects to
https://, preserving host and path. - [L,R=301] —
R=301is a permanent redirect (SEO-safe);Lstops rewrite processing here.
Variants for Special Environments
Behind a Reverse Proxy or Load Balancer (Cloudflare, nginx)
When Apache receives traffic through a proxy, the %{HTTPS} variable may read off even when the visitor connected via HTTPS. In that case, use the X-Forwarded-Proto header instead:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If your server handles both direct access and proxy traffic, combine both conditions with [OR]:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Redirect to www at the Same Time
If you want to consolidate traffic on https://www.yourdomain.com, add a second rule after the HTTPS redirect:
RewriteEngine On
# Step 1: HTTP → HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Step 2: non-www → www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Common Mistakes and How to Avoid Them
Infinite Redirect Loop
The symptom: your browser shows "This page isn't redirecting properly" or "Too many redirects." The most common causes:
- The
mod_rewritemodule is not enabled in Apache. Check withapachectl -M | grep rewrite. - The SSL certificate isn't installed or isn't listening on port 443 — Apache never sets
HTTPS=on. - You're behind a proxy and using
%{HTTPS}instead ofX-Forwarded-Proto(see the section above). - The
.htaccessfile is in a directory whereAllowOverrideis set toNone— rules are silently ignored.
500 Error After Editing .htaccess
A syntax error in .htaccess causes an immediate 500. Check the syntax with:
apachectl configtest
Also check Apache's error log (/var/log/apache2/error.log or /var/log/httpd/error_log) for the exact line causing the problem.
Redirect Works but Mixed Content Appears
Forcing HTTPS at the server level is only the first step. If your HTML loads resources with an explicit http:// URL (images, scripts, stylesheets), browsers will block them. Solutions:
- Change absolute
http://URLs to protocol-relative (//) or root-relative (/path) URLs. - In WordPress, enable the "Force HTTPS" option in your SSL plugin, or add
define('FORCE_SSL_ADMIN', true);. - Add the
Content-Security-Policy: upgrade-insecure-requestsheader as a temporary measure.
You can explore more SSL security topics in our SSL security article hub.
Verifying the Redirect Works
After saving your .htaccess, test from the command line without following redirects:
curl -I http://yourdomain.com
You should see:
HTTP/1.1 301 Moved Permanently
Location: https://yourdomain.com/
If you get a direct 200, the rule isn't being applied. If you see multiple Location: headers, you have a loop.
To confirm the certificate responds correctly:
curl -I https://yourdomain.com
The result should be HTTP/2 200 (or HTTP/1.1 200) with no certificate warnings.
Quick Reference Table: Scenarios and Recommended Rule
| Scenario | Condition to use | Loop risk |
|---|---|---|
| Direct Apache (no proxy) | %{HTTPS} off |
Low if SSL is active |
| Behind Cloudflare / nginx | %{HTTP:X-Forwarded-Proto} =http |
Medium if proxy doesn't send the header |
| Both (direct + proxy) | Combine with [OR] |
Low |
| Shared hosting (cPanel / Plesk) | %{HTTPS} off usually works |
Very low (SSL managed by panel) |
Key Takeaways
- The three-line minimum rule (
RewriteEngine On,RewriteCond %{HTTPS} off,RewriteRule) covers most situations. - Behind a proxy, use
X-Forwarded-Prototo prevent infinite redirect loops. - A 500 error after saving
.htaccessalmost always means a syntax error — useapachectl configtest. - Forcing HTTPS at the server level doesn't fix mixed content — you also need to update URLs in your HTML.
- Always verify with
curl -Ito confirm the 301 status code andLocationheader. - Once everything is working, consider adding HSTS to enforce the redirect at the browser level.
Need help auditing your server's SSL setup or want an expert to get it right from the start? Reach out to us at elenlace.com — we handle Apache, certificates, and everything in between.
FAQ
Do I need an SSL certificate installed before adding the .htaccess rule?
Yes, absolutely. The rule redirects traffic to https://, but if Apache doesn't have a valid certificate listening on port 443, the browser will show a connection or certificate error. Install the SSL certificate first (Let's Encrypt, cPanel SSL, etc.), then add the redirect rule.
Does a 301 redirect hurt SEO?
No — quite the opposite. A correctly configured 301 redirect passes virtually all link equity to the HTTPS version. Google also actively favors HTTPS sites in rankings. The only real SEO risk is a long redirect chain (HTTP → HTTPS → www → another URL), which you should avoid by consolidating into a single redirect where possible.
Where exactly should I put the code in .htaccess?
Place it at the very top of the file, before any WordPress, Joomla, or application rules. If a RewriteEngine On line already exists, don't duplicate it — simply add the RewriteCond and RewriteRule lines right below that existing line.
Can I use this same rule on shared hosting (cPanel)?
Yes. On most cPanel shared hosting plans, mod_rewrite is already active and AllowOverride All is configured for your public_html directory. If your control panel offers a "Force HTTPS" toggle in the SSL section, use that instead — it generates exactly these rules automatically and eliminates the risk of manual syntax errors.
Prefer it done for you? El Enlace handles hosting and professional web development.
Useful resources
Other providers and guides worth comparing: