If `/?p=123` works while `/sample-post/` returns 404, the content and database are present. The failure sits in URL rewriting or WordPress’s rewrite map, not in the post itself.
Start with evidence and the smallest reversible change; work on staging when possible, preserve the logs and rollback material if production is already down, and keep the objective specific: determine whether rewrite rules, server modules, subdirectory paths, custom post type slugs, or stale flush state causes WordPress URLs to miss.
What the symptom narrows down
- Apache rewrite rules are missing/unreadable or Nginx lacks the WordPress front-controller rule.
- The site moved into or out of a subdirectory without matching base paths.
- A page and custom post type share a slug, or rewrite rules were never flushed after registration changed.
The branches are ordered to protect the strongest evidence around this possibility: apache rewrite rules are missing/unreadable or Nginx lacks the WordPress front-controller rule. The observed scope and logs—not a familiar-looking error screen—decide which one applies.
Routing should be read as a chain of explicit HTTP responses; wordPress, the web server, proxy, CDN, and browser can each redirect or cache independently; the address finally visible in the browser hides that chain; in this guide, the practical goal is to determine whether rewrite rules, server modules, subdirectory paths, custom post type slugs, or stale flush state causes WordPress URLs to miss.
Evidence to collect before the fix
- Compare the plain query URL with the pretty URL and inspect actual HTTP status.
- Save Permalinks once, then inspect the generated rules or
wp rewrite list. - Check web-server configuration and
.htaccessownership without overwriting custom rules. - Search for duplicate page, taxonomy, and post-type slugs.
The sequence moves from observation toward intervention. Preserve the result of the final check—search for duplicate page, taxonomy, and post-type slugs—because it provides a useful comparison after the repair.
Test one hypothesis without losing the baseline
Begin with the first plausible cause: apache rewrite rules are missing/unreadable or Nginx lacks the WordPress front-controller rule. Before changing state, write down what would confirm it and run the first read-only check: compare the plain query URL with the pretty URL and inspect actual HTTP status.
If the result supports that cause, try one bounded repair on staging: restore the standard front-controller rule appropriate to the actual web server and path. If evidence from “Compare the plain query URL with the pretty URL and inspect actual HTTP status” points elsewhere, keep this layer unchanged and move to the next check. That small decision log is far easier to audit than several simultaneous edits.
Apply fixes in the safest order
- Restore the standard front-controller rule appropriate to the actual web server and path.
- Correct the base URL/subdirectory configuration after a migration.
- Resolve slug collisions and flush rules once during activation or administration—not every request.
Before applying “Restore the standard front-controller rule appropriate to the actual web server and path,” name its rollback point and the evidence that will count as success. Afterward, repeat the original request and specifically check whether you can test a post, page, category, feed, pagination URL, and a deliberate missing URL; a changed symptom at that point is new evidence, not permission to make several more changes at once.
Prove recovery
- Test a post, page, category, feed, pagination URL, and a deliberate missing URL.
- Confirm the missing URL returns a real 404 rather than the home page.
- Check canonical URLs after the route change.
One successful refresh is not closure. Keep the incident open until you can also confirm the missing URL returns a real 404 rather than the home page, adjacent paths have not regressed, temporary diagnostics are gone, and another operator can explain what changed.
Prepare a useful escalation if the boundary is outside your control
Capture curl -I or curl -IL output, the canonical host/scheme policy, proxy/CDN rule names, WordPress home and site URL values, and one deep affected path; remove cookies and authorization headers before sharing evidence; include the result of this first observation: compare the plain query URL with the pretty URL and inspect actual HTTP status.
State what was tested, including the result of “Compare the plain query URL with the pretty URL and inspect actual HTTP status,” and what changed between attempts; evidence tied to that observation is safer and more actionable than granting broad access or sending an unnecessary full database export.
Inspect and rebuild rewrite rules deliberately
List the rule that should match the failing path before flushing anything. On staging, save a backup of custom server rules, then perform one controlled flush.
wp rewrite list --match='sample-post' --format=table
wp option get permalink_structure
wp rewrite flush --hard
curl -sS -o /dev/null -D - https://example.com/sample-post/
Interpretation and safety: The –hard option writes server rules only when WordPress supports that environment. Preserve custom directives and use the host’s documented Nginx workflow where .htaccess is not used.
Shortcuts that create a second incident
- Do not call
flush_rewrite_rules()on every page load. - Do not replace server rules without preserving non-WordPress directives.
Evidence log
Primary references
- WordPress common errors — official reference consulted for this guide.
Editorial note: The scenario above illustrates how to approach “Restore the standard front-controller rule appropriate to the actual web server and path”; it is a documented example, not a claim about a reader’s server, so verify the cited documentation, take the appropriate backup, and follow the real environment’s access and change-control rules.