NewTry MagicWP now - first month free
WordPress troubleshooting

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.

Short answer

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.

Diagnosis

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.

CauseHow to checkFix
Stale or missing rewrite rulesThe 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 WordPressThe 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 ignoredOn 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 serveThe 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.
Walkthrough

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.

  1. 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'
  2. Regenerate the rules

    The first thing to try, and frequently the last.

    wp rewrite flush --hard
    wp rewrite list --format=count
  3. 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;
    }
  4. 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 WordPress
  5. Confirm 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' {}
On MagicWP

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.

FAQ

Questions, answered.

Did I lose my posts?
No. The query-string test proves it: the same post that 404s at its permalink loads by ID. Only the mapping from URL to content is broken.
Why does the home page still work?
It is the document root, so it needs no rewrite rule to be found. Every other URL depends on the rule set that is missing, which is exactly why the failure has this shape.
I flushed the rules and nothing changed. What now?
That points one layer out: the server is not handing unknown paths to WordPress at all. Flushing rewrites what WordPress knows, which is useless if the request never reaches it.
Could a plugin have caused this?
Yes — anything that registers a custom post type or taxonomy adds rules, and adding one without flushing leaves the new URLs 404ing until the rules are rebuilt.
Related

If that was not it.

These fail in ways that look similar from the browser.