Type something to search...
How to fix 404 errors on WordPress posts?

How to fix 404 errors on WordPress posts?

If your WordPress posts suddenly return "404 Not Found" while your homepage still works, the most common fix is simply to go to Settings > Permalinks and click "Save Changes" without changing anything. That flushes WordPress's rewrite rules and, on Apache servers, regenerates the .htaccess file. If that doesn't work, the cause is usually a missing or unwritable .htaccess file, a server that isn't passing requests to WordPress, a plugin conflict, or a post whose URL has changed.

404 errors are frustrating for visitors and bad for search rankings, especially when they hit your most important content. This guide walks you through why WordPress posts return 404s, how to tell which cause applies to you, and the exact fixes for Apache, Nginx, and common plugin-related issues.

What Is a 404 Error in WordPress?

A 404 status code means the server received the request but couldn't find anything at that address. In WordPress, pretty URLs like /how-to-bake-bread/ don't correspond to real files on the server. Instead, the web server hands every request to index.php, and WordPress uses its rewrite rules to work out which post, page, or archive you asked for.

When that chain breaks at any point, you get a 404. The two main categories are:

  • Site-wide post 404s: Every post (and often every page) returns a 404, but the homepage and dashboard work. This almost always points to rewrite rules or server configuration.
  • Individual 404s: A single post or a handful of URLs return 404s. This usually means the post was deleted, unpublished, or had its slug changed, or an external link points to the wrong address.

Knowing which one you're dealing with tells you where to start.

Quick Diagnosis Checklist

Before changing anything, answer these questions:

  1. Does the homepage load? If yes, WordPress and the database are working.
  2. Do all posts return 404, or just some? All posts suggests rewrite rules; some posts suggests content or redirect issues.
  3. Does the post load with plain permalinks? Try https://yourdomain.com/?p=123, replacing 123 with the post ID (visible in the edit URL in the dashboard). If this works, the post exists and the problem is with pretty permalinks.
  4. Did anything change recently? Migrations, server moves, plugin installs, permalink changes, and switching from Apache to Nginx are common triggers.

Fix 1: Re-Save Your Permalink Settings

This is the fastest fix and solves the majority of site-wide post 404s.

  1. Log in to your dashboard: Go to /wp-admin/.
  2. Open permalink settings: Navigate to Settings > Permalinks.
  3. Save without changes: Scroll down and click "Save Changes." You don't need to pick a different structure.
  4. Test a post: Open one of your posts in a private browser window.

Saving this screen calls WordPress's rewrite flush, which rebuilds the stored rewrite rules. On Apache, WordPress also tries to write the correct rules to .htaccess.

If you have WP-CLI access, you can do the same thing from the command line:

wp rewrite flush --hard

The --hard flag tells WordPress to update .htaccess as well as the rules stored in the database.

Fix 2: Restore or Repair the .htaccess File (Apache and LiteSpeed)

On Apache and LiteSpeed servers, pretty permalinks depend on the .htaccess file in your WordPress root folder. If it's missing, empty, or overwritten by another tool, every post will return a 404.

Check the File

Connect with SFTP or your host's file manager and look in the folder that contains wp-config.php. Files beginning with a dot are hidden by default, so enable "Show hidden files" in your client if you don't see it.

Replace It With the Default Rules

Back up the existing file first, then make sure it contains the standard WordPress block:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

If WordPress is installed in a subfolder such as /blog/, change RewriteBase / to RewriteBase /blog/ and the last rule to RewriteRule . /blog/index.php [L].

Keep any other rules your security or caching plugins added outside the # BEGIN WordPress and # END WordPress markers. WordPress only manages what's between those markers.

Check File Permissions

If WordPress can't write to .htaccess, the Permalinks screen will show a message with the rules you need to add manually. The usual permission for .htaccess is 644. You can set it over SSH:

chmod 644 .htaccess

Make Sure mod_rewrite Is Enabled

On a server you manage yourself, .htaccess rules only work if Apache's rewrite module is enabled and the site's configuration allows overrides. On Debian and Ubuntu:

sudo a2enmod rewrite
sudo systemctl restart apache2

Then check your virtual host configuration. The directory block for your site needs AllowOverride All, otherwise Apache ignores .htaccess entirely:

<Directory /var/www/example.com/public_html>
    AllowOverride All
    Require all granted
</Directory>

Restart Apache after changing it. On shared hosting, this is already configured for you.

Fix 3: Configure Nginx for Pretty Permalinks

Nginx doesn't read .htaccess files at all. If you moved to Nginx, or your host uses it, re-saving permalinks won't fix 404s because the server itself needs a rule to send requests to WordPress.

In your site's server block, the location / section should include a try_files directive like this:

location / {
    try_files $uri $uri/ /index.php?$args;
}

For a WordPress install in a subfolder:

location /blog/ {
    try_files $uri $uri/ /blog/index.php?$args;
}

After editing, test the configuration and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

On managed hosts that use Nginx, this rule is normally in place already. If it isn't, contact support rather than trying to edit server files you don't control.

Fix 4: Look for Plugin Conflicts

Plugins that register custom post types, change URL structures, handle redirects, or add security rules can all break rewrite rules. To test for a conflict:

  1. Deactivate all plugins: Go to Plugins > Installed Plugins, select all, and choose "Deactivate" from the bulk actions menu.
  2. Re-save permalinks: Visit Settings > Permalinks and click "Save Changes."
  3. Test a post: If it now loads, a plugin was the cause.
  4. Reactivate one at a time: Turn plugins back on individually, testing a post after each, until the 404 returns.

If you can't reach the dashboard, rename the wp-content/plugins folder to plugins-off via SFTP to deactivate everything at once, then rename it back and reactivate plugins individually.

With WP-CLI, you can do this without the dashboard:

wp plugin deactivate --all
wp rewrite flush --hard

If you use a staging site, testing there avoids disrupting live visitors.

Custom Post Types Returning 404s

If only posts of a custom post type return 404s, the rewrite rules probably weren't flushed after the post type was registered. Re-saving permalinks usually fixes this. If you're a developer registering post types in a plugin, flush rules on activation rather than on every page load, since flushing is expensive:

<?php
/**
 * Plugin Name: Sajjad Portfolio Post Type
 */

function sajjad_register_portfolio_cpt() {
    register_post_type( 'portfolio', array(
        'label'        => __( 'Portfolio', 'sajjad' ),
        'public'       => true,
        'has_archive'  => true,
        'rewrite'      => array( 'slug' => 'portfolio' ),
        'show_in_rest' => true,
        'supports'     => array( 'title', 'editor', 'thumbnail' ),
    ) );
}
add_action( 'init', 'sajjad_register_portfolio_cpt' );

function sajjad_portfolio_activate() {
    sajjad_register_portfolio_cpt();
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'sajjad_portfolio_activate' );

function sajjad_portfolio_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'sajjad_portfolio_deactivate' );

Also check for slug clashes. If a custom post type uses the slug news and you also have a page called "News," one of them may hijack the other's URLs.

Fix 5: Check for Theme Issues

It's rare, but a theme can cause 404s through a broken 404.php template, custom rewrite code in functions.php, or queries that modify the main loop incorrectly. Switch temporarily to a default theme such as Twenty Twenty-Five under Appearance > Themes and test a post. If the problem disappears, the theme's code is responsible.

Fix 6: Fix Individual Post 404s

When only specific URLs return 404s, the rewrite rules are probably fine. Instead, check the post itself.

Is the Post Published?

Open Posts > All Posts and check the status. Drafts, pending posts, private posts (for logged-out visitors), and scheduled posts all return 404s to the public. Posts in the trash return 404s as well.

Did the Slug Change?

If you edited a post's URL slug, old links will break. WordPress tries to redirect old slugs automatically using the _wp_old_slug meta field, but this doesn't cover every case, such as changing the permalink structure or moving content between post types.

Did You Change the Permalink Structure?

Switching from /2026/09/post-name/ to /post-name/ changes every URL on your site. WordPress can often guess the right destination, but external links and search engine results may still hit 404s. Set up redirects from the old structure to the new one.

Fix 7: Set Up Redirects for Moved Content

Redirects send visitors and search engines from an old URL to the new one with a 301 (permanent) status.

Using a Plugin

The free Redirection plugin is the most popular option. It lets you add redirects under Tools > Redirection, and it logs 404 errors so you can see which broken URLs visitors are actually hitting. SEO plugins like Yoast SEO Premium and Rank Math also include redirect managers.

Using .htaccess

For a small number of redirects on Apache, add rules above the WordPress block:

Redirect 301 /old-post-name/ https://yourdomain.com/new-post-name/

To redirect a date-based structure to a plain post-name structure:

RedirectMatch 301 ^/[0-9]{4}/[0-9]{2}/(.+)$ https://yourdomain.com/$1

Using Nginx

location = /old-post-name/ {
    return 301 https://yourdomain.com/new-post-name/;
}

Using PHP

If you need a code-based redirect that works on any server, you can hook into template_redirect in a small custom plugin or your child theme's functions.php:

function sajjad_redirect_old_posts() {
    if ( ! is_404() ) {
        return;
    }

    $redirects = array(
        '/old-post-name/'     => '/new-post-name/',
        '/another-old-slug/'  => '/another-new-slug/',
    );

    $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
    $path        = wp_parse_url( $request_uri, PHP_URL_PATH );

    if ( isset( $redirects[ $path ] ) ) {
        wp_safe_redirect( home_url( $redirects[ $path ] ), 301 );
        exit;
    }
}
add_action( 'template_redirect', 'sajjad_redirect_old_posts' );

For more than a handful of URLs, a plugin like Redirection is easier to maintain.

Fix 8: Check URLs After a Migration

After moving your site to a new domain or host, 404s often appear because:

  • The .htaccess file wasn't copied: Hidden files are easy to miss during manual transfers.
  • The site URL is still the old one: Check Settings > General and confirm both "WordPress Address (URL)" and "Site Address (URL)" are correct.
  • Old URLs remain in content: Internal links may still point to the old domain. A search-and-replace tool such as Better Search Replace, or WP-CLI's wp search-replace, updates them safely, including serialized data.
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --skip-columns=guid --dry-run

Remove --dry-run once you're happy with the preview. Back up the database before running the real replacement.

Find 404s Before Your Visitors Do

Fixing 404s you know about is only half the job. To find the rest:

  • Google Search Console: The Indexing > Pages report lists URLs Google tried to crawl that returned "Not found (404)."
  • The Redirection plugin's 404 log: Shows real requests hitting missing URLs, along with referrers.
  • Crawlers: Desktop tools like Screaming Frog SEO Spider crawl your site and flag broken internal links.
  • Broken link checkers: Plugins can scan content for broken links, though running them continuously on shared hosting can be heavy, so schedule scans rather than leaving them always on.

Not every 404 needs fixing. Random bot requests for files that never existed can be ignored. Focus on URLs that had real traffic, backlinks, or search visibility.

Create a Helpful 404 Page

Even with careful maintenance, some visitors will land on missing pages. A good 404 page keeps them on your site. In a block theme, edit the 404 template under Appearance > Editor > Templates > Page: 404. Add a short message, a search block, and links to popular posts or categories. In a classic theme, the 404.php template in your child theme controls this page.


FAQ: Fixing WordPress 404 Errors

This almost always means WordPress's rewrite rules or your server's rewrite configuration are broken. Re-saving Settings > Permalinks or restoring the default .htaccess rules usually fixes it.

On Nginx servers, WordPress can't write server rules, so you need a try_files directive in the server configuration. On Apache, check that .htaccess is writable, that mod_rewrite is enabled, and that AllowOverride All is set.

A few 404s for content that genuinely no longer exists are normal. However, 404s on pages that had traffic or backlinks lose that value, so redirect them to the most relevant live page.

No. Search engines often treat mass redirects to the homepage as soft 404s, and visitors find them confusing. Redirect to the most relevant replacement, or let genuinely removed content return a 404 or 410.

Open the post in the editor and look at the browser's address bar. The number after post= in the URL is the post ID.

Yes. A cache can keep serving an old 404 response after you've fixed the underlying issue. Clear your caching plugin, server cache, and CDN cache after making changes.

The rewrite rules probably weren't flushed after the post type was registered, or its slug clashes with a page or another post type. Re-save permalinks first, then check for slug conflicts.


Conclusion

Most WordPress post 404 errors come down to rewrite rules, and the fix is often as simple as re-saving your permalink settings. When that doesn't work, check your .htaccess file on Apache, your try_files rule on Nginx, and test for plugin or theme conflicts. For individual broken URLs, confirm the post is published and set up 301 redirects for anything that has moved.

Once the immediate problem is solved, keep an eye on Google Search Console and a 404 log so you catch new broken links early. A clear, helpful 404 page and a habit of adding redirects whenever you change a URL will keep both visitors and search engines happy.

Tags :
Share :

Related Posts

What are the best WordPress security plugins?

What are the best WordPress security plugins?

The best WordPress security plugins for most sites are Wordfence, Sucuri Security, Solid Security, MalCare, All-In-One Security (AIOS), Patchstack, a

Dive Deeper
What is the difference between posts and pages in WordPress?

What is the difference between posts and pages in WordPress?

The main difference between posts and pages in WordPress is that posts are timely, dated entries that appear in your blog feed, archives, and RSS fee

Dive Deeper
How much does it cost to build a WordPress website?

How much does it cost to build a WordPress website?

Building a WordPress website can cost anywhere from roughly the price of a domain and a year of budget hosting, if you do it yourself with free tools

Dive Deeper