I have some custom permalinks for my custom post types, that look like so:


I wrote a generate_rewrite_rules function for the permalinks related to that custom post type.

However, any regular pages I create via WP's interface show up as 404s, while those custom permalinks still work. I'm convinced it's an Apache problem. Can't figure out what's wrong.

I have an editable .htaccess in place, with the normal stuff inside...

# 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

My apache conf file for the relevant server:

<Directory />
        Options FollowSymLinks
        AllowOverride All
<Directory /path/to/folder>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
        Order allow,deny
        allow from all

EDIT Running WP 4.8.1, on Ubuntu 14.04

EDIT 2: Just noticed this is a WP 404, not an apache 404. So this is down to my rewrite rules, and I've noticed that the rewrite is looking for every page being one of my custom taxonomy, as in (index.php?product-category=$matches[1]) and that's why I get the 404. Of course this shouldn't happen.

How do I fix it? My function is a bit of a nest.

function custom_rewrite_rules($wp_rewrite) {
    $newRules = array();
    $terms = get_terms( array(
        'taxonomy' => 'product-category',
        'hide_empty' => false,
    ) );

    foreach ($terms as $term) {   
        $post_query = new WP_Query( array(
            'post_type' => 'custom_product',
            'posts_per_page' => -1,
            'tax_query' => array(
                    'taxonomy' => 'product-category',
                    'field'    => 'slug',
                    'terms'    => $term->slug,
                    'include_children' => false
        if ( $post_query->have_posts() ) : while ( $post_query->have_posts() ) : $post_query->the_post();
                $parent = get_term( $term->parent, 'product-category');
                $newRules['products/' . $parent->name . '/' . $term->name . '/'. get_post_field( 'post_name', get_the_ID() ) . '$'] = 'index.php?taxonomy=product-category&post_type=custom_product&product-category='.$parent->slug.'&product-category='.$term->slug.'&custom_product='. get_post_field( 'post_name', get_the_ID() );
            } else {
                $newRules['products/' . $term->name . '/'. get_post_field( 'post_name', get_the_ID() ) . '$'] = 'index.php?taxonomy=product-category&post_type=custom_product&product-category='.$term->slug.'&custom_product='.get_post_field( 'post_name', get_the_ID() );

            $parent = get_term( $term->parent, 'product-category');
            $newRules['products/' . $parent->name . '/' . $term->name . '$'] = 'index.php?taxonomy=product-category&product-category='.$parent->slug.'&product-category='.$term->slug;
        } else {
            $newRules['products/' . $term->name . '$'] = 'index.php?taxonomy=product-category&product-category='.$term->slug;
    $newRules['products/(.+)/(.+)/?$'] = 'index.php?post_type=custom_product&custom_product=$matches[2]';
    $newRules['products$'] = 'index.php?post-type=page&pagename=product-categories';

    $wp_rewrite->rules = $newRules + $wp_rewrite->rules;

1 Answer 1


Most likely, you have created custom permalinks that are in conflict with default WP permalinks. Unfortunately, WP doesn't validate permalinks rules, and it is very easy to create conflicted permalinks rules.

Rules have priority hierarchy, and when resolving any request, WordPress goes through the list of rules, until it matches first one. It is possible that you have created rule that has overridden the default rule so that normal pages depending on that rule can't be resolved anymore.

You need to be very careful with permalinks rule, especially not to replace default rules without suitable replacement.

  • Looks like that's exactly what I did, posted that function above. I don't know how that happened, as I thought WP would make sure that they would only apply to the post type and taxonomy specified.
    – herrrrd
    Sep 13, 2017 at 8:40
  • Based on your code, rules you have added look OK, because they have fixed string prefix (products), so it should not cause problems with default rules. WP returns 404 if the custom rule is resolved OK, but the returning page has no posts to show. And, the rule that you have for 'index.php?product-category=$matches[1]' will only display posts for the default post type (posts), and if it has no results, it will return 404. If you need this to work with custom post only, you should consider include post type in this rule: 'index.php?product-category=$matches[1]&post_type=custom_product'. Sep 13, 2017 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.