How to Debug and Trace Apache mod_rewrite Rules

Debugging Apache mod_rewrite rules can feel like solving a puzzle in the dark because URL transformations happen entirely behind the scenes. This article provides a straightforward guide on how to enable, configure, and interpret Apache’s built-in logging mechanism to trace exactly how your rewrite rules are being executed. By using the LogLevel directive, you can pinpoint why a redirect is failing, see which specific regex patterns are matching, and observe the final URI output in real-time.

Step 1: Configure LogLevel for mod_rewrite

In older versions of Apache (v2.2 and earlier), debugging required a dedicated RewriteLog directive. In modern Apache environments (v2.4 and later), this has been replaced by a highly flexible, per-module LogLevel configuration.

To start tracing your rules, you need to modify your Apache configuration file (usually httpd.conf, apache2.conf, or your specific VirtualHost file). Add or modify the LogLevel directive to target mod_rewrite specifically:

LogLevel alert rewrite:trace3

The rewrite:trace3 argument tells Apache to capture the internal execution steps of the rewrite engine. You can adjust the verbosity by changing the trace level from trace1 (low detail) up to trace8 (extreme detail, which shows every regex comparison step). For most debugging scenarios, trace3 or trace5 strikes the perfect balance between useful information and log readability.

Step 2: Locate and View the Log File

Because mod_rewrite now hooks into Apache’s standard error logging infrastructure, the trace output will be sent directly to your defined ErrorLog.

Once you have saved your configuration changes, restart or reload your Apache server to apply them:

sudo systemctl restart apache2   # Debian/Ubuntu
sudo systemctl restart httpd     # CentOS/RHEL

Next, open your terminal and use the tail command to watch the error log in real-time while you refresh the problematic URL in your browser:

tail -f /var/log/apache2/error.log | grep rewrite

Step 3: Interpret the Trace Output

When you trigger a rewrite rule, the log will output a detailed sequence of events. Understanding how to read these lines is key to fixing your configuration.

A typical log entry looks like this:

[rewrite:trace3] [pid 1234] mod_rewrite.c(480): [client 192.168.1.50:50321] 192.168.1.50 - - [example.com/sid#7f8c123][rid#7f8c456/initial] applying pattern '^old-path/(.*)' to uri 'old-path/page.html'
[rewrite:trace2] [pid 1234] mod_rewrite.c(480): [client 192.168.1.50:50321] 192.168.1.50 - - [example.com/sid#7f8c123][rid#7f8c456/initial] rewrite 'old-path/page.html' -> 'new-path/page.html'
[rewrite:trace1] [pid 1234] mod_rewrite.c(480): [client 192.168.1.50:50321] 192.168.1.50 - - [example.com/sid#7f8c123][rid#7f8c456/initial] internal redirect with /new-path/page.html [INTERNAL REDIRECT]

When analyzing this output, pay close attention to three main milestones:

Step 4: Clean Up Your Production Environment

Enabling trace logs creates massive amounts of disk I/O and can quickly fill up your server’s storage. Once you have successfully diagnosed and fixed your rewrite rules, revert the LogLevel back to its default state:

LogLevel warn

Safely reload your server one last time to ensure performance returns to normal.