.htaccess causing "Too Many Redirects", can't find the conflict with default settings

Operating system: Debian
OS version: 10

I am using the default Virtualmin install and whatever settings come with it. Trying to get a site up and running, but the .htaccess is causing the “Too Many Redirects” issue. Here are the only lines in the .htaccess:

RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteRule ^([^/]*)-([^/]*).html$ /index.php?page=torrent-details&name=$1&torrent_id=$2 [L]
RewriteRule ^([^/]*)_([^/]*).html$ /index.php?page=userdetails&id=$1&name=$2 [L] 

I have removed everything under Server Configuration > Website Redirects.

Any idea where the conflict might be coming from?

Remove the second line, and retry. Make sure to test it with another browser or incognito mode.
With that you can easiliy test if thats the cause, if not then I assume its the folder? part of it which causes it. Not sure though.
And maybe I confuse something here, but isn’t there a missing condition?

It’s probably because after the HTTP to HTTPS redirection occurs, evaluation ends and the loop starts again with the new URL. Because you have no RewriteCond to assess whether the protocol is already HTTPS, it matches the first rule, redirects (HTTPS to HTTPS!) and ends because you’ve set the L flag. Then it starts again, matches the first rule and ends because you’ve set the L flag… :slight_smile:

RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
...static-to-dynamic rules follow this...

That should fix it.

https://htaccess.madewithlove.be?share=6c40316c-e06c-433c-b991-9e97b098e893 shows the rules evaluating. Change the test URL to HTTP to see the first redirect, as this tester does not show multiple iterations of mod_rewrite rules in one pass.

If you like this tester, they made a CLI version in February 2020: https://madewithlove.com/our-htaccess-tester-tool-has-new-features/

If you wanted to support both HTTP and HTTPS, this also works:

RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^([^/]*)-([^/]*).html$ http%1://%{HTTP_HOST}/index.php?page=torrent-details&name=$1&torrent_id=$2 [QSA,NE,NC,L]
RewriteRule ^([^/]*)_([^/]*).html$ http%1://%{HTTP_HOST}/index.php?page=userdetails&id=$1&name=$2 [QSA,NE,NC,L] 

Unfortunately, the MWL tester doesn’t understand the inverted matching of “%{HTTPS}s ^on(s)|”, but it definitely works in the real world. if you need to dev the rewrites, just use plain HTTP then add the HTTPS conversion back in after confirming the rules work.

https://stackoverflow.com/a/9725036/253139 explains the logic of how the HTTP/HTTPS detection works.

There’s a few quite useful tools online which I use frequently. htaccess.madewithlove.be, regex101.com, PerishablePress’s rewrite article, explainshell and others have saved me many hours of frustration.


Thanks so much @chriswoods The one supporting both HTTP and HTTPS worked. I think it may redirecting https to http, but that is something I will have to look into more later.

If you F12 and watch the network requests (make sure you enable “Preserve log”), do you see multiple 301 or 302 redirects? If you could post your entire .htaccess for the site (put it inside a code block) it might become more obvious.

Also, how do you have Webmin and Virtualmin set up? If you want to globally redirect HTTP to HTTPS without individual htaccess rules, there’s some options you can customise.

I set up a redirect through Virtualmin from one domain to another, and it adds this to the Server Directives configuration (Virtualmin > Services > Configure Website):

RedirectMatch 301 ^/(?!.well-known)(.*)$ "https://newdomain.com/"

That neatly omits the .well-known directory from being redirected, so you can still use HTTP authentication for Let’s Encrypt and other stuff. The Virtualmin GUI method is explained at https://www.virtualmin.com/documentation/tutorial/how-to-manage-url-redirects.

Have you copied this site’s htaccess or Virtualmin settings from another virtual site? Have you tweaked any other Virtualmin settings related to web site hosting or domains?

1 Like

That’s pretty clever. I’ll steal it for sure.


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.