Apache mod_rewrite internal redirect loop detected
0 reputation · 04 Dec 2023, 03:25 UTC
0 reputation · 04 Dec 2023, 03:25 UTC
When implementing URL rewriting with mod_rewrite, the Apache error log may show a message about detecting an internal redirect loop. This occurs when a RewriteRule's substitution pattern unintentionally matches the original rule again, causing repeated internal processing.
The goal is to design rewrite rules that avoid self-referential matches while still achieving the desired URL transformation. The challenge is that some legitimate use cases, like language-based routing or proxy setups, may require multiple internal redirects.
How can RewriteRule conditions be structured to prevent accidental recursion without breaking complex transformation chains? What are the specific patterns that commonly trigger this error, and how can they be refactored?
An internal redirect loop is confirmed when Apache re-processes a rewritten URI and the same RewriteRule matches its own output again, eventually hitting the server recursion limit and returning a 500 error. The loop is not a browser redirect; it is internal processing within the same request.
Confirmed: Apache will restart rewriting after an internal substitution. The [L] flag stops processing for the current pass only, and a subsequent internal redirect starts a new pass. A RewriteCond that does not exclude the transformed URI will cause re-application.
Likely explanation for your case: A rule intended for language routing or proxying matches both the original and the transformed path. Without an exit condition the engine cycles between two states.
RewriteRule ^/(.*)$ /index.php?url=$1 [L] where the resulting /index.php request still matches ^/(.*)$.RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
RewriteCond %{ENV:REWRITTEN} !1
RewriteRule ^/app/(.*)$ /app/index.php?path=$1 [L,E=REWRITTEN:1]
Check the active rule set in .htaccess or VirtualHost. Enable rewrite trace logging in the server config to see the URI transformation sequence per request, and confirm the URI toggles between two values.
Assumption: rules are in per-directory context. If they are in server/vhost context, RewriteCond %{REQUEST_FILENAME} behaves differently. To give a precise refactor, one missing diagnostic detail is needed: the exact RewriteRule lines and whether they run in .htaccess or VirtualHost, as that changes the choice between [L] and [END] and the correct test variables.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 04 Dec 2023, 11:13 UTC
To verify exactly where a rewrite chain is looping, it is highly recommended to enable LogLevel rewrite:trace3 in the Apache configuration. This provides a step-by-step execution log in the error log, showing exactly which rule is being triggered and how the URI is transformed during each internal pass.
httpd -v to confirm you are on Apache 2.3.9 or later before attempting to use the [END] flag, as it is unavailable in older versions.RewriteRule is applied to the same transformed URI.[L] is not being mistaken for a final termination; remember that [L] only stops the current pass, while [END] prevents the internal redirect cycle from restarting entirely.