Skip to content
Products
AI Website Builder New VPS Hosting Cloud Servers Web Hosting Dedicated Servers Domains
Company
About Documentation Support Center Contact Get Started Call +91 75795 45488
Login
Hosting Panel — cPanel & Billing Console Panel — VPS Management
ALL SYSTEMS OPERATIONAL
WordPress

WordPress Custom Post Type 404: Fix Broken Archive & Single Pages

Getwebup 6 min read

Regular posts and pages load fine. Your product, portfolio, or listing archive - the custom post type you or a plugin registered - throws a 404 instead. That's a different bug than a broken site-wide permalink, and it needs a different fix.

Symptom: What You're Actually Seeing

Before you touch any settings, confirm this is really a CPT-scoped issue and not a general permalinks problem:

  • Regular posts (/blog/my-post/) and pages load normally.
  • The custom post type's archive (/portfolio/) or a single entry (/portfolio/my-project/) returns a 404.
  • The content exists in wp-admin - you can open and edit it there, it's just not resolving on the front end.
  • It often started right after installing a new theme, updating a plugin, or migrating the site to Getwebup.

If every URL on the site 404s, that's a site-wide rewrite failure (missing .htaccess, mod_rewrite disabled) - a different problem with a different fix. This post is specifically for when only the custom post type's URLs are broken.

Why This Happens

1. Rewrite rules were never flushed after the post type was registered

WordPress caches its full list of URL patterns (the rewrite rules) in the database, in the rewrite_rules option. Registering a new post type with register_post_type() doesn't automatically add its rules to that cache - WordPress only rebuilds it when you visit Settings → Permalinks and save, when a theme/plugin explicitly calls flush_rewrite_rules() on activation, or when the cache is otherwise cleared. Deploy new CPT code without triggering a flush, and every archive/single URL for it 404s even though the post type itself works fine in wp-admin.

2. has_archive is missing, false, or was recently changed

If the archive URL specifically 404s but single posts of that type load fine, check how the post type was registered:

register_post_type('portfolio', array(
    'public'      => true,
    'has_archive' => true,
    'rewrite'     => array('slug' => 'portfolio'),
    // ...
));

If has_archive is false or absent, there is no archive template registered at all - WordPress correctly 404s because that URL was never meant to exist. This is common after a plugin update quietly changes its own registration arguments.

3. A plugin registering the CPT was deactivated, updated, or replaced

Post types created by plugins (WooCommerce's product, an events plugin, a portfolio plugin) only exist while that plugin is active. Deactivate it, hit a fatal error during an update, or swap it for a different plugin, and the post type registration disappears - but the posts stay in the database as orphaned content with no matching URL structure. Check Plugins for anything recently updated or deactivated, and confirm the CPT still shows up under its own admin menu.

4. A theme switch dropped custom code that registered the CPT

If the post type was registered in functions.php rather than a plugin, it lives and dies with the active theme. Switching themes - even to preview one - removes that registration instantly, and every URL for it 404s until the code is added to the new theme or moved into a small custom plugin (which is the more resilient place for it).

5. The rewrite slug collides with an existing page or post

If you have a Page named "Portfolio" at /portfolio/ and a custom post type also registered with the slug portfolio, WordPress's rewrite priority can resolve the URL to the wrong object, or 404 depending on order of registration. This shows up as intermittent-looking 404s that seem to appear or disappear after saving something unrelated.

The Fix

  1. Log in to wp-admin.
  2. Go to Settings → Permalinks.
  3. Without changing the structure, click Save Changes.

This forces a full rewrite-rule rebuild, which covers cause #1 in the vast majority of cases. If the archive loads now, you're done.

Step 2 - Flush from the command line if you have SSH/WP-CLI

Faster and more reliable than clicking through wp-admin, especially right after a deploy:

wp rewrite flush --hard

--hard also updates .htaccess on Apache, not just the database option - useful if the two have drifted apart.

Step 3 - Confirm the post type is still registered correctly

Check via WP-CLI:

wp post-type list --format=table

If your custom post type isn't in the output, the registration itself is missing - go back to cause #3 or #4 and confirm the plugin is active or the theme code is present. If it is listed, check its has_archive and rewrite values directly:

wp eval 'var_dump(get_post_type_object("portfolio"));'

Step 4 - Rule out a slug collision

In wp-admin, search Pages and Posts for anything using the same slug as your CPT's rewrite base. If you find a collision, either rename the Page's slug or set a distinct rewrite => array('slug' => 'portfolio-items') on the post type, then flush rewrite rules again.

Step 5 - Check for a caching or security plugin short-circuiting the request

Full-page cache and some security plugins can serve a cached or generic 404 before WordPress's own rewrite logic runs. Temporarily deactivate caching plugins (or purge the page cache and any server-level cache like Varnish or LiteSpeed Cache) and reload the archive URL directly to rule this out.

Prevention

PracticeWhy it matters
Call flush_rewrite_rules() only on plugin activation/deactivation hooks, never on every page loadFlushing on every request is a well-known performance mistake, but skipping it entirely on activation is what causes this exact 404
Register custom post types in a small custom plugin, not functions.phpSurvives theme switches and previews; content and its URL structure don't disappear with a design change
Re-save permalinks (or run wp rewrite flush) after every plugin update that registers post typesUpdates can silently change has_archive or rewrite arguments
Give custom post type slugs that won't collide with page titlesAvoids intermittent 404s from rewrite-priority conflicts
Test archive and single URLs after any migration to Getwebup, not just the homepageMigration tools reliably move content but don't always trigger a rewrite-rule rebuild on the new server

If you've gone through all five causes and the archive still 404s, check the actual server error log in cPanel (Metrics → Errors) for anything below WordPress's own layer - a rogue .htaccess rule or an Nginx location block can override WordPress entirely and won't show up in any of the above.

Frequently asked questions

Why does the single post page work but the archive page 404s?

That almost always means has_archive is set to false (or missing) in the post type's registration. Without it, WordPress never creates an archive route for that post type in the first place, so the 404 is technically correct behavior until you add has_archive => true and flush rewrite rules.

Do I need to flush rewrite rules every time I edit a post in that custom post type?

No. Rewrite rules only need to be rebuilt when the post type's registration changes - a new slug, a plugin update, activating/deactivating the plugin that registers it, or a theme switch. Editing content never requires a flush.

I flushed rewrite rules and it still 404s. What's next?

Confirm the post type is actually registered with wp post-type list - if it's missing, the plugin or theme code that creates it isn't running (check for a fatal error in your error log). If it is listed, check for a slug collision with an existing page, and temporarily disable caching plugins to rule out a cached 404 response.

Does this happen with WooCommerce products too?

Yes - the product post type is registered by the WooCommerce plugin itself, so deactivating WooCommerce, hitting an update error, or switching to an incompatible theme can 404 your shop and product pages the same way. The fix is identical: confirm WooCommerce is active and error-free, then flush permalinks from WooCommerce > Status > Tools or Settings > Permalinks.

Will migrating my site to Getwebup break my custom post type URLs?

Not on its own, but the rewrite-rules cache doesn't always survive a server change cleanly. After any migration, visit Settings > Permalinks and click Save once - it costs nothing and rebuilds the rules cleanly on the new server.

#wordpress #custom-post-type #404-error #permalinks #rewrite-rules #wp-cli

Keep reading

Chat with Support