Fixing WordPress permalink issues and 404 errors

How to fix WordPress pages and posts returning 404 errors when the homepage loads fine, covering permalink settings, .htaccess regeneration, server configuration and WooCommerce product 404s.

If your WordPress homepage loads fine but every other page, post or custom post type returns a 404 "not found" error, the problem is almost always related to your permalink settings or your server's URL rewriting.

This is different from a single missing page, which usually means that content has been deleted, moved to draft or had its address changed. When every page except the homepage returns a 404, it's a problem with how your server handles addresses rather than with your content.

It's usually one of the quicker WordPress problems to fix.

The simplest fix, and the one that works most often, is to regenerate WordPress's rewrite rules by resaving your permalink settings.

On Apache and LiteSpeed servers, saving your permalinks rewrites the section of your .htaccess file between the # BEGIN WordPress and # END WordPress markers. WordPress leaves the rest of the file alone,1 but if the file contains custom redirects or security rules, download a copy first so you can put it back if anything goes wrong.

Then go to Settings → Permalinks in the WordPress dashboard. Don't change anything. Just click Save Changes at the bottom of the page. WordPress regenerates its rewrite rules and, on Apache servers, updates .htaccess if it can write to it.

Refresh one of the pages that was returning a 404. If it loads, the problem is solved. This works because the rewrite rules that tell your server how to turn tidy addresses into WordPress pages can become stale or corrupted, particularly after updates, migrations or server changes.

The same rewrite rules power the WordPress REST API at /wp-json/, which the block editor uses to save your work. If the editor is also showing "Updating failed. The response is not a valid JSON response", see our guide to fixing the not a valid JSON response error.

Regenerate .htaccess

If resaving permalinks didn't work, the .htaccess file in your WordPress root folder may be corrupted, missing or not writable.

Connect via SFTP or your hosting file manager and check whether .htaccess exists in the same folder as wp-config.php. Files starting with a dot are often hidden, so you may need to turn on "show hidden files". If it's missing, WordPress may not have been able to create it, usually because of file permissions or ownership.

If the file exists, rename it to .htaccess_old rather than deleting it, so you keep a copy of any custom rules it contained. Then resave your permalinks from Settings → Permalinks to generate a fresh one. If WordPress still can't write the file, your host can check the permissions and ownership for you.2

If you need to create the file by hand, create a new file called .htaccess in the WordPress root folder containing WordPress's default rules:3

# 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

These rules are for a standard single-site installation at the root of your domain. If WordPress runs in a subfolder, the folder name needs to appear in both the RewriteBase line and the last RewriteRule line, for example RewriteBase /blog/ and RewriteRule . /blog/index.php [L].4 Multisite networks use different rules again,3 so check with your host or developer before replacing the file on a multisite.

If your old file contained other rules you still need, such as redirects or security rules added by a plugin, copy them back from .htaccess_old one block at a time, checking the site after each. A broken rule in .htaccess can cause a 500 internal server error or a 403 forbidden error, and conflicting redirects can cause a redirect loop.

Check that URL rewriting is enabled

On Apache servers, WordPress's tidy permalinks need the mod_rewrite module. If it's been disabled (for example, after a server change or a move to a new host), no amount of .htaccess editing will fix the 404s, because the server isn't processing rewrite rules at all.

Go to Tools → Site Health → Info and open the Server section. The "Are pretty permalinks supported?" line shows whether WordPress thinks rewriting is available.5 If it says No, contact your hosting provider and ask them to check URL rewriting is enabled.

Check Nginx configuration

If your server runs Nginx rather than Apache, there's no .htaccess file to fix. Nginx doesn't read .htaccess files at all, which is a common source of confusion when a site moves from an Apache server to an Nginx one.

Nginx needs WordPress's rewrite rules in its own server configuration.6 Your hosting provider normally sets this up, but if the rules are missing or wrong, every page except the homepage returns a 404. Contact your host and ask them to check the Nginx configuration includes WordPress's standard rules. This is a server change, so it's one for your host rather than something to try yourself on shared hosting.

Check for custom post type issues

If the 404s only affect one type of content, such as a custom post type created by a plugin, that post type's rewrite rules may need refreshing.

Deactivate and reactivate the plugin that creates the post type, then go to Settings → Permalinks and click Save Changes (with a copy of .htaccess saved first, as above). Deactivating a plugin briefly switches its features off for visitors, so do this at a quiet time.

If the 404s continue, check whether the post type's address conflicts with an existing page. For example, a custom post type using "projects" in its addresses and a page called "Projects" can conflict and cause 404s on one or both.

Fix WooCommerce product 404s

WooCommerce products are a custom post type, so all of the general permalink issues above can affect them. There are a few WooCommerce-specific things to check too.

Check the product's Catalog visibility setting in the Publish box on the product edit screen. A product set to "Hidden" won't appear in the shop or search results, but it should still load at its own address. If it's returning a 404 instead, the problem is more likely permalinks or rewrite rules.

Also check the product's stock status. Out-of-stock products don't return 404s by default, but some themes and plugins hide or redirect out-of-stock products.

WooCommerce's product permalink settings are in the Product permalinks section of Settings → Permalinks, below WordPress's own settings.7 Check the product base is set as you expect and doesn't clash with an existing page. Changing it changes the address of every product, so only change it if you intend to, and set up redirects from the old addresses if you do.

Check for conflicting plugins

Plugins that change addresses, handle redirects, create custom post types or change WordPress's rewrite rules can all cause 404 errors.

If the 404s started after installing or updating a plugin, try deactivating it. Our guide to recovering a site broken by an update covers rolling back safely. If the 404s appeared without any obvious change, deactivate plugins one at a time and test whether the pages load after each one, ideally on a staging copy or at a quiet time.

SEO plugins, redirect plugins and plugins that change the WordPress login or admin address are common culprits.

Need help with persistent 404s?

If pages and posts keep returning 404 errors after working through these steps, my WordPress development service and emergency WordPress support can help diagnose and resolve permalink, server configuration and URL rewriting issues. For server configuration you can't change yourself, your hosting provider is the best first contact.


  1. misc.php (insert_with_markers), WordPress source code on GitHub. ↩

  2. Changing file permissions, WordPress Advanced Administration Handbook. ↩

  3. Apache HTTPD / .htaccess, WordPress Advanced Administration Handbook. ↩ ↩

  4. class-wp-rewrite.php, WordPress source code on GitHub. ↩

  5. class-wp-debug-data.php, WordPress source code on GitHub. ↩

  6. Nginx, WordPress Advanced Administration Handbook. ↩

Adam Greenough

Written by Adam Greenough

Freelance web developer with over 15 years of experience building and fixing WordPress sites. I work with businesses across the UK on everything from emergency support to full builds.

Need emergency WordPress support today?

If your site is down, hacked or throwing errors, send me the details and I will assess the problem quickly. Support starts from £50, you will get a fixed quote before any work begins, and if I cannot fix the issue, you will not pay.