skip to Main Content

Whenever a non-existent file is trying to be accessed (I am using a subfolder configuration for my Multisite network) it creates a 500 error and results in the following error in the Apache log "Request exceeded the limit of 10 internal redirects due to probable configuration error.".

I am using the standard .htaccess code (see below) that WordPress provided i.e. not using any custom code/rules

# BEGIN WordPress

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteBase /
    RewriteRule ^index.php$ - [L]
    
# add a trailing slash to /wp-admin
    RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]
    RewriteRule . index.php [L]
</IfModule>

# END WordPress

For example, if I go to /blahblah/ or /blahblah/1.jpg I get a 404 not found error page – all good.

However, if I go to /blahblah/wp-content/uploads/sites/1/1.jpg I get a 500 error and it seems to trigger some kind of redirect loop which ultimately results in an Apache core error. This only seems to happen when trying to access an asset within a deleted site.

2

Answers


  1. RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
    

    If you request /blahblah/wp-content/uploads/sites/1/1.jpg then the above rule rewrites the request to wp-content/uploads/sites/1/1.jpg and the rewrite engine starts over. The potential issue here is that if /wp-content/uploads/sites/1/1.jpg does not exist then this same rule matches again and rewrites the request to wp-content/uploads/sites/1/1.jpg again.

    (If the file did exist then the preceding rule would prevent further processing and no additional rewrite occurs.)

    Ordinarily on Apache, if a URL passes through unchanged then processing stops. However, this is not something that should necessarily be relied upon as it’s prone to error (different configs etc.). If that does not happen for whatever reason then the same rewrite will happen repeatedly, resulting in a rewrite-loop to the same non-existent file (and a 500 internal server error response).

    I suspect that is what’s happening here.

    However, on WordPress it is not advisable to manually edit the directives between the # BEGIN WordPress and # END WordPress comment markers, since WordPress itself tries to manage this section. You can, however, add an additional rule to the top of the file (before the # BEGIN WordPress comment marker) to avoid such a rewrite-loop.

    For example:

    # Prevent further processing if "/wp-content" and related URLs are requested
    RewriteRule ^wp-(content|admin|includes) - [L]
    
    # BEGIN WordPress
    :
    

    You do not need to repeat the RewriteEngine directive, that already occurs later in the file (in the WordPress code block).

    This would allow any (rewritten) request of the form /wp-content/uploads/sites/1/1.jpg that does not map to a physical file to simply fall through to an Apache generated "404 Not Found" response.

    In light of the above it would be beneficial to also add an exception for .php URLs (as rewritten by the rule that follows the rule discussed above), which could also suffer the same fate if they don’t map to physical files. So, after the rule added above, at the top of the file before the WordPress code block:

    # Prevent further processing if any ".php" URLs are requested
    RewriteRule .php$ - [L]
    

    Alternatively, if you were to edit the WordPress code block you would use the END flag (instead of L) on the last 3 rules. This is an Apache 2.4 flag that prevents any further processing by the rewrite engine. (The WordPress code block as written is intended to work on Apache 2.2 and possibly earlier.)


    in the Apache log "Request exceeded the limit of 10 internal redirects due to probable configuration error."

    You can temporarily increase the LogLevel (Apache 2.4+) in the server config to see the exact nature of the rewrite loop. For example:

    LogLevel rewrite:trace5
    
    Login or Signup to reply.
  2. Try the below code

    # BEGIN WordPress
    
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
        RewriteBase /
        RewriteRule ^index.php$ - [L]
    
        # add a trailing slash to /wp-admin
        RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
    
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]
    
        # Handle requests for non-existent files in deleted sites
        RewriteCond %{REQUEST_URI} ^/[_0-9a-zA-Z-]+/wp-content/uploads/sites/[^/]+ [NC]
        RewriteRule ^ - [L]
    
        RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
        RewriteRule ^([_0_9a-zA-Z-]+/)?(.*.php)$ $2 [L]
        RewriteRule . index.php [L]
    </IfModule>
    
    # END WordPress
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search