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:trace3The 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/RHELNext, 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 rewriteStep 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:
- applying pattern: This shows the exact regular expression Apache is testing and the current string it is testing against. If your rule isn’t executing at all, check if the URI matches this pattern.
- rewrite: This line confirms that a pattern match was successful and displays how the URI is being transformed step-by-step.
- internal redirect / pass through: This indicates what Apache decides to do with the final string, whether it maps it to a physical file, passes it to another module, or issues a 301/302 browser redirect.
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 warnSafely reload your server one last time to ensure performance returns to normal.