Home » httpd » Use FallbackResource for WordPress instead of mod_rewrite

by comment

Use FallbackResource for WordPress instead of mod_rewriteUse FallBackResource as a great alternative to using mod_rewrite to direct Apache to send all requests for non-existing files/directories to a script in WordPress. Htaccess and Server Config enabled.

WordPress Default .htaccess Rewrite Rules

This is the default WordPress .htaccess that says, if request is not already for /index.php and the requested file is NOT an existing directory or file, than internally rewrite requests to /index.php which is how WP enables pretty-permalinks and other features such as db-enabled 404 detection.

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

Use FallBackResource instead

For WordPress, this works faster, especially when placed in server config context and disabling per-directory htaccess configs.

FallbackResource /index.php

Fallback Resource


You want a single resource (say, a certain file, like index.php) to handle all requests that come to a particular directory, except those that should go to an existing resource such as an image, or a css file.

As of version 2.2.16, you should use the FallbackResource directive for this:

<Directory "/home/">
FallbackResource /index.php

Changes with Apache 2.4.4 - Add support for the value 'disabled' in FallbackResource. [Vincent Deffontaines]

Apache 2.3.3 - add FallbackResource directive, to enable admin to specify an action to happen when a URL maps to no file, without resorting to ErrorDocument or mod_rewrite. PR 47184 [Nick Kew]

However, in earlier versions of Apache, or if your needs are more complicated than this, you can use a variation of the following rewrite set to accomplish the same thing:

<Directory "/home/">
  RewriteBase "/"

  RewriteCond "/home/{REQUEST_FILENAME}" !-f
  RewriteCond "/home/{REQUEST_FILENAME}" !-d
  RewriteRule "^" "index.php" [PT]

If, on the other hand, you wish to pass the requested URI as a query string argument to index.php, you can replace that RewriteRule with:

RewriteRule "(.*)" "index.php?$1" [PT,QSA]

FallBackResource in .htaccess

Note that these rulesets can be used in a .htaccess file, as well as in a <Directory> block.


FallbackResource Directive

Description:Define a default URL for requests that don't map to a file
Syntax:FallbackResource disabled | <var>local-url</var>
Default:disabled - httpd will return 404 (Not Found)
Context:server config, virtual host, directory, .htaccess
Compatibility:The disabled argument is available in version 2.4.4 and later

Use this to set a handler for any URL that doesn't map to anything in your filesystem, and would otherwise return HTTP 404 (Not Found). For example

FallbackResource /not-404.php

will cause requests for non-existent files to be handled by not-404.php, while requests for files that exist are unaffected.

It is frequently desirable to have a single file or resource handle all requests to a particular directory, except those requests that correspond to an existing file or script. This is often referred to as a 'front controller.'

In earlier versions of httpd, this effect typically required mod_rewrite, and the use of the -f and -d tests for file and directory existence. This now requires only one line of configuration.

FallbackResource /index.php

Existing files, such as images, css files, and so on, will be served normally.

Use the disabled argument to disable that feature if inheritance from a parent directory is not desired.

In a sub-URI, such as this sub-URI has to be supplied as local-url:

<Directory "/home/">
    FallbackResource /index.php
<Directory "/home/">
    FallbackResource disabled

FallbackResource in mod_dir.c

Like Rich Bowen says, there is a lot of bad info out on the web for Apache, specifically for htaccess. So you need to get in the habit of reading the C source code for any software you care about. Here is the latest mod_dir.c code taken straight from Apache. Obviously much easier to read in vim or SublimeText, emacs, etc., but for the rest of you: ./modules/mappers/mod_dir.c

static const command_rec dir_cmds[] =
    AP_INIT_TAKE1("FallbackResource", ap_set_string_slot,
                  (void*)APR_OFFSETOF(dir_config_rec, dflt),
                  DIR_CMD_PERMS, "Set a default handler"),

static int fixup_dflt(request_rec *r)
    dir_config_rec *d = ap_get_module_config(r->per_dir_config, &dir_module);
    const char *name_ptr;
    request_rec *rr;
    int error_notfound = 0;

    name_ptr = d->dflt;
    if ((name_ptr == NULL) || !(strcasecmp(name_ptr,"disabled"))){
        return DECLINED;
    /* XXX: if FallbackResource points to something that doesn't exist,
     * this may recurse until it hits the limit for internal redirects
     * before returning an Internal Server Error.

    /* The logic of this function is basically cloned and simplified
     * from fixup_dir below.  See the comments there.
    if (r->args != NULL) {
        name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL);
    rr = ap_sub_req_lookup_uri(name_ptr, r, r->output_filters);
    if (rr->status == HTTP_OK
        && (   (rr->handler && !strcmp(rr->handler, "proxy-server"))
            || rr->finfo.filetype == APR_REG)) {
        ap_internal_fast_redirect(rr, r);
        return OK;
    else if (ap_is_HTTP_REDIRECT(rr->status)) {

        apr_pool_join(r->pool, rr->pool);
        r->notes = apr_table_overlay(r->pool, r->notes, rr->notes);
        r->headers_out = apr_table_overlay(r->pool, r->headers_out,
        r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out,
        error_notfound = rr->status;
    else if (rr->status && rr->status != HTTP_NOT_FOUND
             && rr->status != HTTP_OK) {
        error_notfound = rr->status;

    if (error_notfound) {
        return error_notfound;

    /* nothing for us to do, pass on through */
    return DECLINED;

static int dir_fixups(request_rec *r)
    if (r->finfo.filetype == APR_DIR) {
        /* serve up a directory */
        return fixup_dir(r);
    else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
        /* No handler and nothing in the filesystem - use fallback */
        return fixup_dflt(r);
    return DECLINED;

More Reading


Comments Welcome

Information is freedom. Freedom is non-negotiable. So please feel free to modify, copy, republish, sell, or use anything on this site in any way at any time ;)

My Online Tools

Popular Articles
Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two.
-- Richard M. Stallman

It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

+Askapache | |

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service | @Htaccess

↑ TOPMain