WordPress Custom Post Type 404 Error – Rewrite Rules Fix
Solve 404 errors on custom post types by mastering rewrite rules, flushing permalinks, and debugging your registration.
Why Does My Custom Post Type Give a 404?
You've registered a custom post type, created some posts, but when you visit their permalinks, you get a 404 Not Found error. This is a common issue that usually stems from WordPress's rewrite rules not being aware of your new post type.
Common causes include:
- Permalinks not flushed: WordPress stores rewrite rules in the database. After registering a new CPT, you must flush these rules to include the new URLs.
- Conflict with existing slugs: Your CPT slug might clash with a page or another post type.
- Incorrect
rewritearguments: Therewriteparameter inregister_post_type()may be set incorrectly (e.g.,falseor missing). - Hierarchical CPT without proper parents: If your CPT is hierarchical, the URL structure includes parent slugs; missing parents cause 404s.
- Custom taxonomy conflicts: Taxonomies can affect rewrite rules if not handled properly.
wp_options table under the rewrite_rules option. When you add a new CPT, you need to regenerate these rules.
Registering a Custom Post Type with Proper Rewrite Rules
When you call register_post_type(), the rewrite argument controls the permalink structure. Here’s a typical registration that enables rewrite rules:
function register_my_cpt() {
$args = array(
'label' => 'Books',
'public' => true,
'has_archive' => true,
'rewrite' => array(
'slug' => 'books', // URL slug
'with_front' => true, // prepend with front base (e.g., /blog/)
'pages' => true, // pagination support
'feeds' => true, // feeds
),
'supports' => array('title', 'editor', 'thumbnail'),
);
register_post_type('book', $args);
}
add_action('init', 'register_my_cpt');
The slug is the main rewrite base. After registering, you must flush rewrite rules to make the URLs work.
Flushing Permalinks to Fix 404s
Flushing rewrite rules regenerates the entire rewrite rule array. There are three main ways to do this:
1. From the WordPress Admin
Go to Settings → Permalinks and click Save Changes. This triggers a flush without changing anything. It's the easiest and safest method.
2. Using the flush_rewrite_rules() Function
Call flush_rewrite_rules() after registering your CPT. However, do not call it on every page load; it's expensive. Use it on plugin/theme activation/deactivation.
// During activation or after registration
function my_plugin_activate() {
register_my_cpt();
flush_rewrite_rules();
}
register_activation_hook(__FILE__, 'my_plugin_activate');
3. Directly in the Database (Not Recommended)
Deleting the rewrite_rules option from wp_options will force regeneration on the next page load, but this is risky and not recommended.
Understanding rewrite Arguments
The rewrite argument accepts an array or false to disable. Here are the key parameters:
slug: The base slug for the post type. Defaults to the post type name.with_front: Whether to prepend the permalink structure with the front base (e.g., if your permalink settings have a prefix like/blog/). Defaulttrue.pages: Enables pagination for the archive (e.g.,/books/page/2/). Defaulttrue.feeds: Enables feed endpoints. Defaulttrue.ep_mask: Endpoint mask for rewrite rules. Usually not needed.
If you set rewrite to false, the post type will not have any rewrite rules, and its URLs will use the ?post_type=book&p=123 format, which is not SEO‑friendly and may cause 404s if you later enable it.
Debugging Rewrite Rules
When you still get 404s after flushing, use these debugging tools:
- Rewrite Rules Inspector Plugin: This plugin shows all the rewrite rules and helps you see if your CPT's rules are present.
- Check the
rewrite_rulesoption: Useget_option('rewrite_rules')to see the array. Look for patterns likebooks/([^/]+)/?$. - Verify the
has_archiveargument: Ifhas_archiveisfalse, single posts may still work, but archive pages will 404. - Check .htaccess (or nginx config): Ensure the server is configured to handle WordPress’s index.php routing. For Apache, the
mod_rewritemust be enabled. - Review your permalink structure: If you use custom structures like
/%category%/%postname%/, it might interfere. - Clear any caching plugins: Some caching plugins store rewrite rules and may need a purge.
add_rewrite_tag() and add_permastruct() for even more custom rules, but these are advanced and usually not needed for standard CPTs.
Best Practices for CPT Rewrite Rules
- Flush rewrite rules only on activation/deactivation – never on every page load. Use
register_activation_hookandregister_deactivation_hook. - Choose unique slugs that don't conflict with existing pages or post types.
- Set
has_archivetotrueif you want an archive page (e.g.,/books/). - Use
with_frontcarefully – if your site uses a blog prefix like/blog/, decide if you want the CPT to inherit it. - If you change the slug later, you'll need to flush rules again and set up redirects to avoid broken links.
- Consider using
ep_maskto control endpoint masks for additional rewrite rules (advanced). - Test thoroughly after creating the CPT, including single posts, archives, and pagination.
- Keep rewrite rules simple – avoid overly complex structures that are hard to maintain.
Frequently Asked Questions
Click a question to reveal the answer.
FreeLearning365.com@gmail.com
0 Comments
thanks for your comments!