Here is an example from the Apache documentation for enforcing canonical hostnames:

RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*) http://www.example.com/$1 [L,R,NE]

What I would like to know is why the /? is needed. I've tried removing it and everything appears to work the same. I was under the impression that the pattern part of the rewrite rule was compared against what comes after the slash.

3 Answers 3


I recently happened across this issue myself. There is a difference between using RewriteRule in the VirtualHost and as part of an .htaccess file. The following rule will match (with a URL like this: example.com/fruit/apple) if it appears in a .htaccess file:

RewriteRule ^(fruit|fruits)/apple http://newfruitwebsite.com$1 [R=301,L]

but will not match in the VirtualHost context. If we check out the apache docs we can see that:

When using the rewrite engine in .htaccess files the per-directory prefix is automatically removed for the RewriteRule pattern matching and automatically added after any relative (not starting with a slash or protocol name) substitution encounters the end of a rule set.

...but what does this mean? The above rule would not match the same URL if it was placed into the VirtualHost because it doesn't allow a leading slash (/) to be at the start of the string. The apache docs go on to say:

The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a Pattern with ^/ never matches in per-directory context.

...so if we need a slash for .htaccess and no slash for VirtualHost, how do we modify the pattern? You guessed it. We need to add /? to add the following condition in our regex (where our question mark (?) is the quantifier):

  • Has between 0 and 1 / at the beginning of the string.

Now our URL (example.com/fruit/apple) string will match because we are handling the fact that if the rule is in the .htaccess file it will have 0 slashes and if it comes from the virtualHost it will have 1 slashes.

Related Reading:


The {REQUEST_URI} string starts with a / character. Apache changed regex engines when it changed versions, so Apache version 1 requires the leading slash while Apache 2 forbids it! We can satisfy both versions by making the leading slash optional with the expression ^/? (? is the metacharacter for zero or one of the preceding character).

Source: http://www.sitepoint.com/apache-mod_rewrite-examples/

A few more resources which talk about the leading slash


and http://net.tutsplus.com/tutorials/other/a-deeper-look-at-mod_rewrite-for-apache/

  • But the Apache 2.2 documentation has multiple examples with a leading ^/ . E.g. the RewriteCond section has: RewriteRule ^/$ /homepage.std.html [L]. Is that a documentation bug? May 2, 2014 at 2:36
  • It turns out (as I just tested) that the leading / (^/) is required, at least in VirtualHost context. I did not test other contexts. May 2, 2014 at 2:56

All I know is that on Apache 2.4 on CentOS 7, the leading slash is required in a VHost but is forbidden in .htaccess


<VirtualHost *:443>
  ServerName supersite-cms.example.com

  # Forward cms requests to the subsite
  # Note the RewriteRule syntax is different than in .htaccess :|
  RewriteEngine on
  RewriteRule ^/subsite/admin$ https://subsite-cms.example.com/admin [L,R=307,E]

  # ... do other stuff if not redirected


RewriteRule ^subsite/admin$ https://subsite-cms.example.com/admin [L,R=307]

Source: The last 5 hours 26 minutes of my life

  • 1
    You can make the slash optional so that it works in either place: RewriteRule ^/?subsite/admin$ https://subsite-cms.example.com/admin [L,R=307,E] Mar 26, 2021 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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