Took me a few months, but I figured out
what is happening and
why it's happening and even
how to prevent it from happening. And then, after working it all out on my own, I did a Forums search and found the identical explanation. Oops. I even found a post from the one and only jdMorgan showing a better way to prevent it. But I've got a couple of residual questions.
Situation: Error Logs periodically say
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
It only happens with requests that are blocked in mod_rewrite for user-agent or referer or whatnot, not with core-level Deny from directives.
Changing the LogLevel is out, since I'm on shared hosting and that's a config-file setting. And the requests are supposed to get a 403, so they do end up in the right place. They just take a nanosecond longer and make a little more work for the server.
So I'm left with testing on myself like an old-fashioned medical researcher. What I see is
Forbidden
You don't have permission to access {pagename} on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
My first thought was some glitch in mod_rewrite so the [F] flag didn't carry its implied [L]. But changing them all to [F,L] didn't make any difference.
:: pause here for inspiration to strike ::
A 403 is not only a slam-the-door-in-your-face. It's also a special kind of rewrite, because the user gets sent to the 403 page, which happens to be called "forbidden.html" (host's default name, requiring no ErrorDocument directive). Along the way to pick up their 403 page, they run into the rule that sent them there in the first place:
RewriteRule (\.html|/)$ - [F]
Fresh request for html file, fresh door-slamming, fresh request for "forbidden.html" file, fresh door-slamming... until Apache catches on and says Enough Is Enough.
D'oh!
I've got a cluster of <Files> exemptions, including robots.txt and forbidden.html-- but they don't do any good here, because the request never makes it as far as the core.
My original fix was to add another Condition to each of the affected Rules:
RewriteCond %{REQUEST_FILENAME} !forbidden
(or)
RewriteCond %{REQUEST_URI} !forbidden
Either one works. The much better fix, courtesy jdMorgan, is to put a conditionless Rule at the very beginning of your Rewrites:
RewriteRule forbidden\.html - [L]
(Modified to fit my own naming, duh.)
______
Residual questions: How come this doesn't happen all the time, everywhere? I would expect every single question about using mod_rewrite for lockouts to be followed with a plaintive post saying "Now I'm getting a bunch of internal-redirect errors".
And, odder still: These new improved redirectless 403s don't show up in the Error Log at all. Not even as the usual "client denied by server configuration". They're in the Access Log as 403. But what's keeping them out of the error log?