404 on every page except the home page
A very specific pattern with a very short list of causes. Your posts still exist; the router in front of them is not routing.
404 Not Found — the requested page could not be found.
The home page is the one URL that needs no rewrite rule, which is why it is the only survivor. Confirm by requesting a post with a query string instead of its permalink — if that loads, the content is fine and the rewrite layer is the whole problem.
What causes it, most likely first.
Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.
| Cause | How to check | Fix |
|---|---|---|
| Stale or missing rewrite rules | The query-string form of a post loads and the pretty permalink does not. Nothing about the content differs between the two requests. | Regenerate the rules. Saving the permalink settings does this through the interface; on the command line it is a single call. |
| The web server does not send unknown paths to WordPress | The 404 is the web server's own page rather than the theme's. WordPress never ran, so it cannot have produced it. | Add the front-controller fallback so any path that is not a real file is handed to index.php. Without it only the document root resolves. |
| AllowOverride is off so .htaccess is ignored | On Apache, the file exists and is correct and changing it has no effect at all. | Enable AllowOverride for the directory, or move the equivalent rules into the virtual host where they are always read. |
| A permalink structure the site cannot serve | The problem began immediately after the permalink structure changed, and reverting to plain permalinks restores everything. | Pick a structure and regenerate the rules. A leading category or custom-post-type base that collides with an existing page path is the usual trap. |
Fixing it, step by step.
Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.
Prove the content is still there
If this loads, nothing is lost and the fix is entirely in the rewrite layer.
curl -sS -o /dev/null -w '%{http_code}\n' 'https://example.com/?p=1'Regenerate the rules
The first thing to try, and frequently the last.
wp rewrite flush --hard wp rewrite list --format=count
Check the server actually falls back to index.php
This is the nginx form. Without it, only paths that exist on disk are served.
location / { try_files $uri $uri/ /index.php$is_args$args; }Restore a known-good .htaccess on Apache
The stock block. If writing it changes nothing, AllowOverride is off and the file is being ignored.
# BEGIN WordPress RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPressConfirm a real permalink now resolves
Ask WordPress for a URL it generated itself, so there is no chance of testing a path that never existed.
wp post list --post_type=post --posts_per_page=1 --field=url | xargs -I{} curl -sS -o /dev/null -w '%{http_code}\n' {}
What the platform takes off the list.
The front-controller fallback is part of every site's nginx configuration from the moment it is created, so the most common version of this — a server that only serves files that exist on disk — cannot occur. There is no .htaccess in the request path to be ignored, overwritten by a plugin, or lost in a restore, because the rules live in the site's own server config rather than in a file inside the webroot.
Questions, answered.
Did I lose my posts?
Why does the home page still work?
I flushed the rules and nothing changed. What now?
Could a plugin have caused this?
If that was not it.
These fail in ways that look similar from the browser.