How to Force HTTPS using .htaccess

By 

Updated on

5 min read

Htaccess Force HTTPS

After installing an SSL certificate for your domain, the next step is to make sure all visitors are served over HTTPS. The simplest way to do this on an Apache server is with a few rewrite rules in a .htaccess file.

If you have SSH root access to the server, the preferred approach is to set up the redirection in the virtual host configuration instead. Virtual host directives are read once at startup, while Apache re-reads .htaccess on every request, which adds a small overhead. For shared hosting or environments where you cannot edit the virtual host, .htaccess is the way to go.

How .htaccess Works

.htaccess is a per-directory configuration file for Apache. When Apache serves a request, it looks for a .htaccess file in the requested directory and applies any directives it finds. The file is usually placed in the domain root directory, but you can have additional .htaccess files in subdirectories.

You can edit the file over SSH, SFTP, or through your hosting panel’s file manager. Changes take effect immediately with no server restart required.

Redirect HTTP to HTTPS

Open (or create) the .htaccess file in your domain’s root directory and add the following rules at the top, before any existing directives:

htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Here is what each line does:

  • RewriteEngine On - Enables the Apache rewrite engine.
  • RewriteCond %{HTTPS} off - Matches only when the incoming connection is plain HTTP. This condition prevents a redirect loop, because once the visitor is on HTTPS the condition is no longer true.
  • RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] - Redirects the request to the same host and URI over HTTPS with a 301 (Moved Permanently) status code. For example, http://example.com/about becomes https://example.com/about.

The %{HTTP_HOST} variable contains the domain name the visitor requested, and %{REQUEST_URI} is the path portion of the URL. Apache preserves the query string automatically unless you override it, so a request such as http://example.com/page?ref=test still becomes https://example.com/page?ref=test.

Save the file and test in your browser. All HTTP requests should now redirect to HTTPS.

Redirect HTTP to HTTPS and WWW to Non-WWW

Most sites pick either the www or non-www version as the canonical domain and redirect the other. To redirect both HTTP to HTTPS and www to non-www in a single rule set, add the following:

htaccess
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

Replace example.com with your actual domain. The [OR] operator means the rewrite rule fires when either condition is true: the connection is not HTTPS, or the hostname starts with www. The [NC] flag makes the hostname check case-insensitive.

Redirect HTTP to HTTPS and Non-WWW to WWW

If you prefer the www version of your domain, reverse the logic:

htaccess
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

This redirects both plain HTTP requests and bare-domain requests to https://www.example.com.

Adding HSTS

Once you have confirmed that HTTPS works correctly, you can add an HTTP Strict Transport Security (HSTS) header. This tells browsers to always use HTTPS for your domain, even if the user types http:// in the address bar:

htaccess
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

The max-age value is in seconds. The example above sets it to one year. Add this line below your rewrite rules. The mod_headers Apache module must be enabled for this directive to work.

Warning
Test your HTTPS setup thoroughly before enabling HSTS. Once browsers cache the header, they will refuse to load the site over HTTP for the duration of max-age. If you use includeSubDomains, every subdomain must already support valid HTTPS, otherwise those subdomains can become unreachable in the browser.

Verifying the Redirect

After saving the .htaccess file, verify that the redirect works as expected. You can use curl with the -I flag to check the response headers without downloading the page body:

Terminal
curl -I http://example.com

A working redirect returns a 301 status and a Location header pointing to the HTTPS URL:

output
HTTP/1.1 301 Moved Permanently
Location: https://example.com/

If your site also redirects www to non-www, or the other way around, you may see more than one redirect before the request reaches the final HTTPS URL.

Test both the www and non-www variants to make sure they all end up at your canonical URL.

Troubleshooting

Redirect loop (ERR_TOO_MANY_REDIRECTS)
This usually means the RewriteCond %{HTTPS} off line is missing or incorrect. Without it, HTTPS requests are redirected again, creating an infinite loop. If your site sits behind a trusted load balancer or reverse proxy that terminates SSL, Apache may not see the original request as HTTPS. In that case, you may need to check the forwarded protocol header instead:

htaccess
RewriteCond %{HTTP:X-Forwarded-Proto} !https

Only use this pattern when your proxy is configured to set X-Forwarded-Proto correctly for every request.

500 Internal Server Error after editing .htaccess
A syntax error in the file causes Apache to return a 500 error. Check the Apache error log (usually /var/log/apache2/error.log or /var/log/httpd/error_log) for the specific line that failed. Common causes are a missing RewriteEngine On line or a typo in a RewriteCond variable name.

mod_rewrite is not enabled
The rewrite rules require mod_rewrite. On Debian and Ubuntu, enable it with:

Terminal
sudo a2enmod rewrite
sudo systemctl restart apache2

On shared hosting, mod_rewrite is almost always enabled by default. If it is not, contact your hosting provider.

Conclusion

For the best performance, set up HTTPS redirects in the Apache virtual host configuration when you have server access. The .htaccess approach covered here is the practical alternative for shared hosting environments where virtual host files are not available.

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page