When WordPress posts return 404 after a migration—or permalinks “stop working” while the homepage still loads—the posts are often still in the database. Pretty permalinks depend on server rewrite rules. If those rules are missing, outdated, or written for the wrong server type, only the front page (and sometimes Admin) keep working.
Work this checklist in order. Prefer staging when you can. Take a backup before editing .htaccess, nginx config, or flushing rewrites on production. Once pretty URLs load again, restore only changes that are safe and recheck homepage, a few posts, categories, and Admin. If one covered WordPress issue is clearly to blame and you want help, use the $99 one-time fix after you can authorize access.
Define what failed
- Confirm the homepage returns 200 while a known post or page URL returns 404 (not a blank page or redirect loop).
- Try the same post using the plain form
?p=ID (from Posts → All Posts → hover the title). If that loads but the pretty URL 404s, the content exists and the rewrite layer is the problem.
- If the whole site is offline, shows a critical error, or redirects endlessly, use the matching checklist first: site down, critical error, or too many redirects.
- If Admin itself will not load, fix that with admin login not working before you rely on Settings → Permalinks.
Quick triage map
| What you observe | Likely layer | First useful check |
Homepage OK; every pretty URL 404s; ?p= works | Rewrites | Flush permalinks; Apache .htaccess or nginx try_files |
| Started right after a migration or PHP/host change | Server rules | Ask the host whether the stack is Apache or nginx; do not paste Apache-only rules onto nginx |
| Only some custom post types 404 | Plugin rewrites | Flush permalinks after reactivating that plugin; check its rewrite settings |
| 404 with a redirect chase between HTTP/HTTPS or www | Canonical redirects | Fix the loop with the redirect checklist, then return here |
| True HTTP 403/500/502 instead of WordPress 404 | Server/proxy | 403/500/502 checklist |
Safe triage order
- Flush permalinks from Admin. Go to Settings → Permalinks, leave the structure as you want it, and save (even without changing anything). That regenerates WordPress rewrite rules. Retest a post URL. If Admin is reachable and this alone fixes it, stop here and document the change.
- Identify Apache versus nginx with your host. On Apache, WordPress usually needs an
.htaccess file with the standard rewrite block and AllowOverride (or equivalent) enabled for that directory. On nginx, .htaccess is ignored—advice that only edits .htaccess will silently do nothing. Ask the host which stack you are on before you edit files.
- Repair Apache rewrites carefully. If the host confirms Apache, back up the current
.htaccess, then ensure the WordPress rewrite rules are present (Settings → Permalinks → Save often rewrites this file when it is writable). Do not delete host or security rules you do not understand—ask the host which lines are required. After any edit, retest posts and restore the backup if the site worsens.
- Fix nginx with the host (not a copied
.htaccess). For a root-served WordPress site, hosts often use a front-controller pattern similar to try_files $uri $uri/ /index.php?$args; in the site config. Exact directives vary by host, and subdirectory installs need a matching path. Ask your host to confirm the front-controller path matches your public site location, including any subdirectory, back up the config, validate it before reloading nginx, and retest. Do not invent a full server block from a random blog post.
- Check plugin-held and stale rewrites. Security, multilingual, membership, and “custom permalink” plugins can own rewrite rules. On staging, disable non-essential rewrite plugins one at a time, flush permalinks after each change, and retest. Restore only changes that are safe; keep a faulty rewrite plugin disabled until it is repaired or replaced. Reactivate only safe plugins, one at a time, and retest.
- Confirm Site Address and paths after migration. Check that Site Address (home) points to your public site and WordPress Address (siteurl) points to the WordPress installation. Use the intended HTTPS hostname and preserve each correct path; a subdirectory installation may need different paths. Wrong URLs can produce 404s or loops—see also too many redirects when the browser reports a redirect loop instead of a clean 404.
- Retest the full path. Open several posts and pages, a category or tag archive if you use them, and one direct media-file URL. Test attachment pages only if your site enables them; an expected redirect to the media file is not a permalink failure. Purge page cache and CDN cache after rewrite fixes so you are not reading a cached 404.
Common causes
- Pretty permalinks enabled, but rewrite rules never flushed after a move.
- Missing or non-writable
.htaccess on Apache; AllowOverride None blocking rewrites.
- nginx site without a WordPress-friendly
try_files (or host equivalent)—.htaccess edits change nothing.
- CDN or reverse proxy caching old 404 responses after you already fixed origin rules.
- Plugin custom post types registered too late, or rewrite plugins left half-disabled after migration.
- Mixed case, trailing-slash, or subdirectory path mismatches after changing hosts.
When a $99 one-time fix fits
Request the $99 one-time WordPress fix if you want help with one clearly defined permalink/404 issue on one WordPress site. Name whether the homepage works, whether ?p= works, when it started, and whether the host is Apache or nginx if you know. We confirm the scope before work begins. Send credentials only through the private access link provided after your request is accepted.
Full rebuilds, new custom features, full migrations, account-wide host outages, and multiple unrelated issues are outside this offer. If a plugin update broke URLs along with other features, see also plugin update broke WordPress site.
Related checks
If the checks do not identify the cause, send your host the failing pretty URL, a working ?p= example if you have one, whether the stack is Apache or nginx, and the start time. Suspected compromise needs a security investigation as well as restoring rewrites.