Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am using the following code to direct all www requests to non-www URLs:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

This works great inside an .htaccess file in the root of my website.
For example, -> -> ->

However, if I move this same code into my VirtualHost configuration, the rewritten URLs contain a double trailing slash. -> -> ->

I fixed it by removing the slash from the rewrite rule:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

But I can't understand the reason for this. Anyone know why?

share|improve this question
up vote 6 down vote accepted

As I understand it, in .htaccess files, the string that mod_rewrite processes in your rule is relative to the directory the .htaccess file is in, so it will not have a / at the start.

In the VirtualHost entry, the string it processes is absolute to the root of the server, and so includes the /.

It makes for subtle differences in how mod_rewrite works.

Here is someone with a similar problem, and solution:

This should work in both cases, assuming I remember my escaping correctly:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^\/?(.*?)$$1 [R=301,L]
share|improve this answer
Thanks! Now I understand why, at least. However, is this better for some reason than just removing the / before the $1 like I show in my original question? – davekaro Jun 11 '09 at 16:04
No better or worse, it is just a block that you can swap between .htaccess of VirtualHost without having to edit it each time to handle context differences. If your way works for you, stick with it! :) – Neobyte Jun 11 '09 at 16:45
Oh that's right - your method will work in both .htaccess and VirtualHost. That makes it better IMO :) – davekaro Jun 11 '09 at 16:50
I had the exact same problem as @davekaro and tried your solution. The last line didn't work for me. RewriteRule ^/?(.*)$$1 [R=301,L] did the trick. – Kenny Rasschaert Jan 16 '11 at 22:44

It is happening because you are capturing an initial slash with (.*) and then applying another slash before it in the new location /$1. It didn't happen before because mod_rewrite behaves slightly differently when operating in a per-directory context as opposed to a per-server context.

You could avoid this by optionally pre-empting the slash. Additionally you can use RedirectMatch in an empty VirtualHost with your surplus domains, which creates a bit less processing and can look cleaner.

<VirtualHost *>
RedirectMatch permanent ^/?(.*)$1

share|improve this answer
Nice. I like the RedirectMatch approach. I will probably go with this since it really is a redirect that I want to accomplish. – davekaro Jun 11 '09 at 16:10

I'm including this post for completeness.

The Apache documentation explains why this behaviour occurs very well and is the reason that the 'RewriteBase' directive exists.

Simply including the 'RewriteBase' directive in your .htaccess file should achieve your desired result.


RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

From the Apache 2.2 mod_rewrite documentation:

The RewriteBase directive explicitly sets the base URL for per-directory rewrites.

My rule of thumb is to almost always use 'RewriteBase' in .htaccess files, and not to use it in the Apache config.

share|improve this answer

I had no time to handle this issue so just rewrite // to / :)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ [R=301,L]
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.