Why are 404s not triggering my 404.php template?

404s are not triggering my 404.php template. The header status code, checked in firebug, is a 404, but the page that gets displayed is like a loop with 0 items (as if this were simply an archive page with 0 entries).

If my permalinks start with /%year%/ and I go to bla.com/9999 (which should produce a 404), WP Debug shows the request as a year:

Read More
Request: 9999
Query String: year=9999
Matched Rewrite Rule: ([0-9]{4})/?$
Matched Rewrite Query: year=9999

If my permalinks start with /%category%/ and I go to bla.com/zzzzz (which should produce a 404), WP Debug shows the request as a category_name:

Request: zzzzz
Query String: category_name=zzzzz
Matched Rewrite Rule: (.+?)/?$
Matched Rewrite Query: category_name=zzzzz

What’s going on? The Show Template plugin (which prints an html comment telling you what template was used to render the page) tells me that the page is rendering with the index.php template. How can I get my 404.php template to load?

Related posts

Leave a Reply

1 comment

  1. I found that the problem was with the otherwise very useful plugin Legacy URL Forwarding.

    It uses the following function (abridged here) with the 404_template hook.

    function doUrlForwarding() {
    
    // make a $query based on the $_SERVER['REQUEST_URI']
    
    // if a post is found, redirect to it
       if (!empty($query->post->ID)) {
          wp_redirect(get_permalink($query->post->ID), '301' );
       }
    }
    
    add_action('404_template','doUrlForwarding');
    

    With the above hook active, the 404.php does not get fired. However, if I place doUrlForwarding at the top of 404.php, it works correctly.

    This answers the mystery, but I still don’t know why using the
    404_template hook is preventing the 404.php template from loading on
    normal 404s. Comment if you have an idea.