RewriteRule Last [L] flag not working?

The [L] rule works fine — you just do not know how it actually works.

When Apache sees the [L] flag and rule matches (rewrite occurs), Apache will go to next iteration and will start matching all rules again from top. The [L] flag means “do not process any rules below in this iteration“.

Yes, the Apache documentation is not 100% clear on this (which means it can be improved), but provides enough info to figure it out eventually.


Apache will stop rewrite cycle in few situations:

  1. No rules matched at all (no rewrite occurred);

  2. “exit now” rule matched (e.g. RewriteRule .* - [L]);

  3. Rewrite occurs, but input URL and final URLs are the same (happens on 2nd-3rd iteration when “badly” written rule rewrites the same URL to the same URL.

    For example RewriteRule (.*) /index.php?page=$1 [L]:

    • /hello => /index.php?page=hello
    • on next iteration it will rewrite /index.php => /index.php?page=index.php
    • and on 3rd iteration it will be /index.php => /index.php?page=index.php .. which makes no sense now);
  4. Rewrite iteration limit is reached (by default = 10) — that’s if you entered infinite rewrite cycle (the value is controlled by LimitInternalRecursion Directive).


With all aforementioned information I can say that your current rules do work as expected. This means that you have to change the logic and get rid of the last rule (maybe handle this moment in parent .htaccess .. or handle it differently — all depends on how your application is built, I do not want to make wild guesses).

Leave a Comment