WordPress Multisite, custom wp-content folder, and Request exceeded the limit of 10 internal redirects

I’m writing a WordPress plugin which uses the settings API from within a class. So the class calls register_settings(), add_settings_field(), and add_settings_section() from within the class which is working well except when I try to submit the form a get a server error with the following error in my logs:

AH00124: 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.

My WordPress install is a bit weird. It’s based on Mark Jaquith’s WordPress Skeleton repo and I have moved my wp-content folder, my wp-config.php file outside WordPress.

Read More

I am also running WordPress through Vagrant so it might be a server config issue. However, I just tried to use my plugin in VVV using a standard WordPress install and its working perfectly.

My WordPress directory looks like this (composer install WP to the app dir):

index.php
wp-config.php
wp-content/
app/

I have added my rewrite logs in a paste bin: http://pastebin.com/QKCFjULZ

My .htaccess file looks like this:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]


RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) /app/$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ /app/$2 [L]


RewriteRule . /index.php [L]

Options -indexes
</IfModule>
# END WordPress

Related posts

1 comment

  1. You have a redirection loop because of these rules

    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) /app/$2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ /app/$2 [L]
    

    Actually, you have to keep in mind that your rules are evaluated even after a rewrite. Thus, if you have /something/wp-xxx/yyy/zzz it will be internally rewritten to /app/wp-xxx/yyy/zzz. But now, as you can see, your rule will match again with new uri /app/wp-xxx/yyy/zzz.

    Proof, looking at your logs

    applying pattern '^([_0-9a-zA-Z-]+/)?(wp-.*)' to uri 'wp-admin/network/options.php',
    rewrite 'wp-admin/network/options.php' -> '/app/wp-admin/network/options.php',
    

    Then you have

    applying pattern '^([_0-9a-zA-Z-]+/)?(wp-.*)' to uri 'app/wp-admin/network/options.php',
    rewrite 'app/wp-admin/network/options.php' -> '/app/wp-admin/network/options.php',
    

    And it goes on and on… until the limit of 10 redirections

    To avoid this behaviour, you need to add some restriction on your rules in order to make sure they won’t be evaluated when they don’t have to. A simple workaround would be to use a negative lookahead pattern to make sure current request does not begin with /app/ before rewriting it:

    RewriteRule ^((?!app/)[^/]+/)?(wp-.+)$ /app/$2 [L]  
    

    Finally, your htaccess could look like this

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    RewriteRule ^index.php$ - [L]
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    
    # Rule 1
    RewriteRule ^([^/]+/)?files/(.+)$ wp-includes/ms-files.php?file=$2 [L]
    
    # Rule 2
    RewriteRule ^((?!app/)[^/]+/)?(wp-.+)$ /app/$2 [L,QSA]
    
    # Rule 3
    RewriteRule ^((?!app/)[^/]+/)?(.+.php)$ /app/$2 [L,QSA] 
    
    RewriteRule ^ index.php [L]
    
    Options -Indexes
    </IfModule>
    # END WordPress
    

    Reminder: the 3 rules are executed only on non-existing files/folders.

    Examples:

    • http://domain.tld/files/something or
      http://domain.tld/xxx/files/something will be internally rewritten
      to /wp-includes/ms-files.php?file=something thanks to Rule 1
    • http://domain.tld/wp-something/somethingelse or http://domain.tld/xxx/wp-something/somethingelse (where xxx can be anything except app) will be internally rewritten to /app/wp-something/somethingelse thanks to Rule 2
    • http://domain.tld/file.php or http://domain.tld/xxx/file.php (where xxx can be anything except app) will be internally rewritten to /app/file.php thanks to Rule 3

Comments are closed.