Debugging Apache Redirects: How to Log and Analyze RewriteRule and RewriteCond Execution


3 views

When dealing with complex URL rewriting scenarios in Apache, there are several ways to examine how your RewriteCond and RewriteRule directives are executing:


# The most important logging directive for mod_rewrite:
LogLevel alert rewrite:trace6

# In your virtual host configuration:

    ServerName example.com
    RewriteLog "/var/log/apache2/rewrite.log"
    RewriteLogLevel 3

For Apache 2.4 and later, the recommended way to debug redirects is through the LogLevel directive:


# Different trace levels provide varying detail:
# trace1 - Basic operation tracking
# trace3 - Includes rule matching details
# trace5 - Shows condition evaluation
# trace8 - Full internal processing details

LogLevel rewrite:trace5

Consider this rewrite scenario that's not behaving as expected:


RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule ^(.*)$ https://new.example.com/$1 [R=301,L]

To debug this, you would:

  1. Set the log level as shown above
  2. Restart Apache
  3. Make test requests
  4. Check error logs (typically /var/log/apache2/error.log)

Sample log entries might look like:


[rewrite:trace2] [pid 12345] mod_rewrite.c(476): [client 192.168.1.1:12345] 192.168.1.1 - - [example.com/sid#7f8a3c0025b8][rid#7f8a3c0a70a0/initial] init rewrite engine with requested uri /test
[rewrite:trace1] [pid 12345] mod_rewrite.c(476): [client 192.168.1.1:12345] 192.168.1.1 - - [example.com/sid#7f8a3c0025b8][rid#7f8a3c0a70a0/initial] pass through /test
[rewrite:trace3] [pid 12345] mod_rewrite.c(476): [client 192.168.1.1:12345] 192.168.1.1 - - [example.com/sid#7f8a3c0025b8][rid#7f8a3c0a70a0/initial] [perdir /var/www/html/] applying pattern '^(.*)$' to uri '/test'

For tracking redirect destinations, you can create a custom log format:


LogFormat "%h %l %u %t \"%r\" %>s %{REDIRECT_URL}e" redirect_log
CustomLog /var/log/apache2/redirect.log redirect_log
  • Missing log entries? Ensure your LogLevel directive is in the correct virtual host or server config section
  • Too much noise? Start with trace3 and increase only when needed
  • Logs too verbose? Use grep to filter: grep "mod_rewrite" error.log

When complex redirect chains aren't behaving as expected, Apache provides multiple logging mechanisms to trace the rewrite execution flow:

  • ErrorLog: Set LogLevel alert rewrite:trace6 in httpd.conf for detailed rewrite debugging
  • CustomLog: Add %{REDIRECT_STATUS}e and %{REDIRECT_URL}e variables to your log format
  • RewriteLog (deprecated in 2.4+): Older method using RewriteLog "/path/to/rewrite.log"

Here's a complete virtual host setup with enhanced rewrite logging:


<VirtualHost *:80>
    ServerName example.com
    LogLevel warn rewrite:trace3
    ErrorLog /var/log/apache2/rewrite_error.log
    
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_URI} ^/legacy/(.*)$ [NC]
        RewriteRule ^(.*)$ https://newserver.com/migrated/%1 [R=301,L]
    </IfModule>

    CustomLog /var/log/apache2/rewrite_access.log combined
</VirtualHost>

A sample debug entry showing rewrite progression:


[rewrite:trace3] applying pattern '^(.*)$' to uri '/legacy/page.html'
[rewrite:trace1] pass through /legacy/page.html
[rewrite:trace3] applying pattern '^(.*)$' to uri '/legacy/page.html'
[rewrite:trace2] rewrite '/legacy/page.html' -> 'https://newserver.com/migrated/page.html'
[rewrite:trace2] forcing redirect with https://newserver.com/migrated/page.html
[rewrite:trace1] escaping https://newserver.com/migrated/page.html for redirect

For multi-server redirect scenarios, add these diagnostic rules before your main ruleset:


RewriteCond %{QUERY_STRING} ^debug=1$ [NC]
RewriteRule ^ - [E=rewrite_debug:1]

RewriteCond %{ENV:rewrite_debug} ^1$
RewriteRule ^ - [E=ORIGINAL_URI:%{REQUEST_URI},E=REDIRECT_TARGET:https://newserver.com%{REQUEST_URI}]

This creates environment variables that can be logged using %{ORIGINAL_URI}e and %{REDIRECT_TARGET}e in your CustomLog format.