ERROR · 09 · VERIFIED 2026-10allwpcare.com/errors/posts-and-pages-return-404-not-found/
Errors / posts-and-pages-return-404-not-found

WordPress Posts Return 404 Not Found (Pages Work)

Posts show a 404 while pages and the dashboard load. The saved rewrite rules are stale, or the server is not passing URLs to WordPress. Flush the rules first.

The message you see
1−Page not found
2−The page you are looking for doesn't exist, or it has been moved. Please try searching using the form below.
Last verified Oct 2026Tested with WordPress 7.1Applies to WordPress 7.1 (tested on Apache) · PHP 7.4+

Why it happens

  • The rewrite rules WordPress saved are out of date. This follows a permalink change made without saving, an import, a restore, or a plugin or theme that adds a post type and never flushed.
  • The permalink structure setting changed, for example after a migration or a settings import, and the saved rules still describe the old structure.
  • On Apache, the .htaccess file is missing, empty or has lost the WordPress block, so pretty URLs never reach WordPress.
  • Apache is not allowed to read .htaccess, because mod_rewrite is off or AllowOverride is set to None for the site folder.
  • On nginx, the site config has no try_files fallback to index.php.
  • A plugin registers a post type or page with the same URL base as your posts, so one rule shadows the other.

How to fix it

Try the fixes in this order. Each one is independent: stop as soon as the error is gone.

FIX 01

Work out which 404 it is

  1. A 404 page in your theme's style, with your header and menu, comes from WordPress. The rewrite rules do not match the URL. Go to the next fix.
  2. A plain page headed "Not Found" with the line "The requested URL was not found on this server" comes from the web server. WordPress never ran. Go to the .htaccess fix, or the nginx fix.
  3. Confirm the post exists and is published. In Posts → All Posts it should show as Published, not Draft, Private or Trash. With WP-CLI, wp post list --fields=ID,post_name,post_status lists the slug and status of each post.
  4. If the post is missing or not published, that is the whole story, and no rewrite fix will help.
FIX 02

Flush the rewrite rules

  1. Open Settings → Permalinks, change nothing, and click Save Changes. This rebuilds the rules and, on Apache, rewrites .htaccess.
  2. With WP-CLI, run wp rewrite flush. It rebuilds the rules saved in the database.
  3. Reload a post. On my test site I made posts return 404 while pages worked by changing the permalink structure with wp option update permalink_structure so the saved rules were stale. wp rewrite flush fixed it at once.
  4. Check the structure with wp option get permalink_structure. It should show what you expect, for example /%postname%/.
FIX 03

Check the permalink structure itself

  1. In Settings → Permalinks, pick the structure you want and save. If posts used to live at /blog/post-name/ or /2024/post-name/, set that exact structure, since a different one changes every post URL.
  2. If a migration or import changed the structure unexpectedly, restore the old one and flush. See how to find and undo changed settings.
  3. Run wp rewrite list to see the rules WordPress holds. It prints each pattern and the query it maps to.
FIX 04

Rebuild .htaccess on Apache

  1. Over SFTP, with hidden files shown, look for .htaccess next to wp-config.php. I tested a site with no .htaccess. Every pretty URL returned Apache's "Not Found" page, pages included.
  2. Save the permalink settings, as above. WordPress writes the file if it can.
  3. If WordPress shows "You should update your .htaccess file now", it cannot write to the file. Add the standard WordPress block by hand. It is shown in the 500 error guide. A broken .htaccess also causes that 500, so keep a copy before you edit it.
  4. wp rewrite flush --hard writes .htaccess only when apache_modules: - mod_rewrite is set in wp-cli.yml. Without it, WP-CLI prints a warning about special configuration and does not create the file.
  5. If the file is correct and the 404 stays, ask your host whether mod_rewrite is on and whether the site folder allows AllowOverride All. I did not test this case.
FIX 05

Add the fallback on nginx

  1. Nginx does not read .htaccess. The site's location / block needs try_files $uri $uri/ /index.php?$args;.
  2. Add it in the server config, test with nginx -t, then reload nginx. If you are on managed hosting, ask the host to check it.
  3. Save the permalinks again afterwards. I did not run nginx for this page, and the line comes from the WordPress nginx documentation.
FIX 06

Look for a conflicting plugin

  1. If only one type of content 404s, such as a custom post type or products, check the plugin that registers it. Re-save permalinks after any change to its slug.
  2. Deactivate other plugins that change URLs, such as redirect or multilingual plugins, one at a time, saving permalinks each time.
  3. Run wp rewrite list and look for two rules that match the same URL. The first match wins.

WordPress turns a pretty address such as /my-post/ into a query using a list of rewrite rules. The list lives in the database, and on Apache a rule in .htaccess hands every unknown URL to index.php. If either part is wrong, WordPress cannot match the address, and you see a 404.

Pages often keep working when posts do not, because the page rule is the last catch-all in the list. A post address that no longer matches its own rule falls through to the page rule, WordPress looks for a page with that name, finds none, and shows the 404.

Reproducing it#

I set the permalink structure to one with a year in it, then changed the saved option back to /%postname%/ without flushing. The result on WordPress 7.1.4:

AddressResult
/hello-world/ (a post)404, with the theme's "Page not found" page
/sample-page/ (a page)200
/2026/hello-world/ (the old structure)200
The theme's 404 page. The heading says Page not found. The text says the page you are looking for doesn't exist, or it has been moved, and there is a search box with a Search button.
The theme's 404 page for /hello-world/ after the rules went stale.

wp rewrite flush then made /hello-world/ return 200 again.

A different failure is a missing .htaccess on Apache. There, posts and pages both return Apache's own "Not Found" page, because the server never hands the address to WordPress. The home page and /wp-admin/ still load, which can look like "only posts are broken".

Five stacked steps. .htaccess hands the address to WordPress. WordPress checks the rules saved in the database. With stale rules no post rule matches, the page rule finds no page, and the theme shows a 404. With no .htaccess, Apache itself says Not Found and WordPress never runs. The fix is to save the permalinks or run wp rewrite flush.
The two 404s look alike and come from different layers.

Which fix to start with#

  1. If the 404 page is styled like your theme, flush the rules. This is the most common case.
  2. If it is a plain server page, fix .htaccess or the nginx config.
  3. If it started after a settings change, check the permalink structure.
  4. If only one custom content type is affected, look at the plugin that registers it.

If a settings change caused it#

A permalink structure that changed by itself is usually the cause behind a repeat 404. An import, a staging copy pushed to live, or a plugin reset can all rewrite it. A snapshot of your settings taken before the change shows the difference between the old and the new structure in plain words.

See what changed, in plain language.

Compare two snapshots, or a snapshot with the live site, and read changes like "Comments: open → closed". The raw key is one click away.

owner-readable diff   raw JSON view  
Get notified

After it is fixed#

Open a post, a page, a category, a tag and a custom post type if you have one. Check the feed at /feed/ as well. Search results use rewrite rules too. If you changed server files, keep a copy of the working version.

If a broken .htaccess makes the whole site show a 403 or a redirect loop instead, see 403 Forbidden and too many redirects.

Related: moving settings from staging to live, and the JSON response error, which has the same cause when the REST address returns a 404.

Sources

  1. WordPress: Apache (httpd) configuration · The standard Apache rewrite block and how it hands URLs to index.php
  2. WordPress: nginx configuration · The try_files fallback to index.php
  3. WP-CLI: wp rewrite flush · Rebuilds the rules, and --hard needs mod_rewrite set in wp-cli.yml
  4. WordPress core: WP_Rewrite · How the saved rules are built from the database
  5. WordPress core: class-wp-rewrite.php (6.8.3) · WP_Rewrite::rewrite_rules() builds the rule list, with the page rules added after the post rules
  6. Apache HTTP Server: mod_rewrite · What RewriteRule and RewriteCond do
  7. MDN: 404 Not Found · What the status means
Newsletter

One email when something breaks or changes.

New plugins and re-tested guides, about twice a month. Never a sales pitch.