Php – Apache reports a 200 status for non-existent WordPress URLs

apache-2.2mod-rewritePHP

The WordPress .htaccess generally has the following rewrite rules:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

When I access a non-existent URL at my website, this rewrite rule gets hit, redirects to index.php, and serves up my custom 404.php template file. The status code that gets sent back to the client is the correct 404, as shown in this HTTP Live Headers output example:

http://www.borngeek.com/nothere/

GET /nothere/ HTTP/1.1
Host: www.borngeek.com
{...}

HTTP/1.1 404 Not Found

However, Apache reports the entire exchange with a 200 status code in my server log, as shown here in a log snippet (trimmed for simplicity):

{...} "GET /nothere/ HTTP/1.1" 200 2155 "-" {...}

This makes some sense to me, seeing as the original request was redirected to page that exists (index.php). Is there a way to force Apache to report the exchange as a 404?

My problem is that bogus requests coming from Bad Guys show up as "successful requests" in the various server statistics software I use (AWStats, Analog, etc). I'd love to have them show up on the Apache side as 404s so that they get filtered out from the stat reports that get generated.

I tried adding the following line to my .htaccess, but it had no effect (I'm guessing for the same reason as the previous redirect rules):

ErrorDocument 404 /index.php?error=404

Does anyone have a clever way to fix this annoyance?

Additional Info:

  • OS is Debian 6.0.4, and Apache version looks to be 2.2.22-3 (hosted on DreamHost)
  • The 404 being sent back to the client is being set by WordPress (i.e. I'm not manually calling header() anywhere)

Best Answer

Try changing [L] to [R=404,L] on your RewriteRule line. This will send a 404 to the client and your server log. To avoid displaying the default error page, you can use ErrorDocument 404 /index.php?error=404 to render the attempt at an ErrorDocument that you said you tried before.

You can also use the WP htaccess Control plugin to help manage your htaccess files across upgrades.