Redirect HTTP to HTTPS in Apache with mod_rewrite: A Practical Guide
Learn how to enforce HTTPS on Apache using mod_rewrite, see a step‑by‑step example, and understand the trade‑offs of .htaccess versus server config.
13 Sept 2025, 13:32 UTC

Problem: Mixed‑content and weak security on a live site
When a website is accessible over both HTTP and HTTPS, browsers issue mixed‑content warnings, and attackers can intercept or alter traffic on the HTTP path. The simplest, most widely supported solution is to redirect every HTTP request to HTTPS at the web‑server level.
Thesis: Use Apache’s mod_rewrite for a reliable, maintainable redirect
mod_rewrite offers a single, declarative rule that can be applied at the global server level or within a directory. It is supported on all mainstream Apache builds, works with virtual hosts, and can be tuned for performance.
1. Where to place the rule
There are two common locations:
- httpd.conf / apache2.conf – placed inside the
<VirtualHost>block, or globally. This requiresAllowOverride Nonefor the directory, so no.htaccessfiles are processed. - .htaccess – placed in the document root. This works only if
AllowOverride FileInfo(orAll) is enabled for that directory.
Using the main configuration file is preferable for performance because Apache does not need to read .htaccess on every request. However, many shared hosts expose only .htaccess, so the rule is still useful there.
2. Crafting the rule
Below is a minimal, production‑ready rule set that checks the HTTPS environment variable and the request host before issuing a 301 (permanent) redirect. The rule is wrapped in <IfModule> to avoid startup errors if the module is missing.
# Ensure mod_rewrite is loaded
RewriteEngine On
# Skip if already HTTPS
RewriteCond %{HTTPS} off
# Optional: enforce a specific host (e.g., example.com)
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.com$ [NC]
# Redirect to https://example.com$request_uri
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Explanation of key terms:
RewriteEngine On– activates the rewrite engine.RewriteCond %{HTTPS} off– matches only when the connection is not already secure.RewriteCond %{HTTP_HOST} …– optional host check to keep the rule scoped.RewriteRule ^ …– the rule pattern (^matches the start of the URL) and the target URL.[L,R=301,NE]– flags:Lstops further processing,R=301sends a permanent redirect,NEprevents URL‑encoding of the target.
Example: Global configuration inside a VirtualHost
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example
# Redirect all HTTP to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
</VirtualHost>
Example: .htaccess in a shared hosting environment
# .htaccess – placed in /public_html
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
3. Testing and troubleshooting
After adding the rule, restart Apache:
# On most systems
sudo systemctl restart apache2
# On CentOS/RHEL
sudo systemctl restart httpd
Verify the module is loaded:
httpd -M | grep rewrite
# or
apachectl -M | grep rewrite
Check that the rule is active by sending a request and inspecting the headers:
curl -I http://example.com
# Expected output snippet:
# HTTP/1.1 301 Moved Permanently
# Location: https://example.com/
If you receive a 404 or no redirect, ensure:
- The
AllowOverridesetting permits.htaccessif you used it. - No conflicting rules earlier in the config.
- The server block matches the requested host.
Trade‑offs and limitations
- Performance:
.htaccessfiles are parsed on every request, adding micro‑latency. For high‑traffic sites, place the rule in the main config. - Redirect loops: A missing
RewriteCond %{HTTPS} offcan cause an infinite loop if the target again triggers the rule. - Complex host setups: If you have multiple subdomains that should all use HTTPS, adjust the host condition or remove it entirely.
- Server restarts: Changing the rule in
httpd.confrequires a restart;.htaccesschanges take effect immediately.
Actionable closing
1. Load mod_rewrite (usually bundled). 2. Decide configuration location based on your environment. 3. Insert the rule above. 4. Restart Apache. 5. Test with curl -I and a browser. 6. Monitor logs for any redirect loops. 7. For production, consider caching the redirect with mod_cache or a CDN for further performance gains.
With this setup, every visitor to http://example.com will be transparently and permanently redirected to https://example.com, eliminating mixed‑content warnings and strengthening your site’s security posture.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.