Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

An even shorter version of my .htaccess file (Last RewriteCond wasn't there) use to work perfectly on my shared web hosting but I've moved to a VPS with Ubuntu 12 with it's stock Apache2 but it simply won't work (even with my changes) and I can't figure out why. I can access example.com or example.com/news but not example.com/article/4

I've put the mod_rewrite block from .htaccess to the vhost config vice versa but that didn't seem to work. I'm guessing it actually tries to go to the article subdirectory or something (which doesn't exist so 404) but I can't work out how to stop it from doing that.

I'm using Apache version 2.2.22

My virtual host file

<VirtualHost 127.0.0.1:80>
DocumentRoot /home/example/www/example.com
RewriteLogLevel 3
RewriteLog /home/example/www/example.rewrite.log
<Directory "/home/example/www/example.com">
AllowOverride All
Options -ExecCGI +FollowSymLinks -Indexes -MultiViews
Order deny,allow
allow from all
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit
</IfModule>
</Directory>
AccessFileName .htaccess
ServerSignature Off
ServerName example.com
ErrorLog /home/example/www/example.log
LogLevel warn
</VirtualHost>

My .htaccess file

ErrorDocument 404 /index.php?404
ErrorDocument 403 /index.php?403
ErrorDocument 500 /index.php?500

Options -ExecCGI +FollowSymLinks -Indexes -MultiViews

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-s
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>

Rewrite redirect loop log when access example.com/article/4

[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] add path info postfix: /home/example/www/example.com/article -> /home/example/www/example.com/article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/article/4 -> article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'article/4'
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] rewrite 'article/4' -> '/index.php?article/4'
[example.com/sid#8475130][rid#867d470/initial] (3) split uri=/index.php?article/4 -> uri=/index.php, args=article/4
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#867d470/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/404 -> 404
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri '404'
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] rewrite '404' -> '/index.php?404'
[example.com/sid#8475130][rid#b6cd7058/initial] (3) split uri=/index.php?404 -> uri=/index.php, args=404
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#b6cd7058/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php

Summarised access log

"GET /article/4 HTTP/1.1" 302 4095 "-"
"GET /404 HTTP/1.1" 200 2405 "-"
share|improve this question

marked as duplicate by Falcon Momot, cole, Ward, MadHatter, Tim Brigham Nov 25 '13 at 18:49

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2 Answers 2

Your original rewrite rules seem simple enough:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-s
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>

Have you tried using the simple SEO/SEF .htaccess such as the one that comes bundled with WordPress? Here it is, but I added the RewriteOptions inherit rule from your original setup:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
share|improve this answer

The logs indicate that your rules are working perfectly.

The index.php script was executed with the arguments ?article/4 and the script responded with a 302 redirect to /404. There is no [R] option in any of those rewrite rules so it must be the script that issued the redirect.

A followup request was made by the browser for /404 and this generated a 200 response.


I suspect you have three problems. The first is that your script issues a 302 response to the URL /404 when it can't find the content. It should issue a 404 response.

The second is that your /404 script issues a 200 response. It should issue a 404 response.

The third is that your index.php script doesn't know how to deal with the argument ?article/4. I don't know how your script works but I would suggest a bit of debugging in the script itself might solve your problem. Use echo() on some of the variables at various stages through the script or something like file_put_contents("/var/log/apache2/example.com.debug.log", time()." ".$variable."\n", FILE_APPEND).

share|improve this answer

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