404 error after a migration or a permalink change
Every page on the site returns a 404 error after moving to a new server, or right after touching the permalink settings: the cause is almost always that the server configuration redirecting URLs into WordPress didn’t come along with the move.
How I go about it
-
Telling the symptom apart
I check whether only the homepage works, typical of a URL rewriting issue, or the whole site loops on redirects, usually a siteurl/home problem rather than a permalink one.
-
Identifying the web server
Apache and Nginx aren’t fixed the same way: Apache reads a .htaccess file at the root, Nginx needs its server block edited directly in its configuration.
-
Re-saving the permalinks
On Apache, I resave Settings > Permalinks to regenerate the .htaccess; on Nginx, I edit the server block to add the equivalent of try_files, since WordPress alone can’t do it.
-
Checking custom post types
If WooCommerce extensions or a page builder register their own post types, I check they’re active when re-saving so their rewrite rules get regenerated too.
-
Checking siteurl and home
I check that these two database options match the real domain after the migration, since a wrong siteurl produces a 404 or a redirect loop that has nothing to do with permalinks.
What I handle regularly
- Every page on the site returns a 404 error after moving to a new host
- Only the homepage works, every other page returns a 404
- WooCommerce product pages are 404 while regular pages work fine
- A redirect loop appears after a domain name change
- Permalinks worked on the old server but not on the new one
How permalinks work, and what breaks after a migration
WordPress’s "pretty" permalinks (Settings > Permalinks) work in two steps: WordPress rewrites raw URLs into clean paths, then the web server has to redirect every request back into index.php so WordPress can resolve it. On Apache, that redirection runs through rewrite rules in .htaccess; on Nginx, through an equivalent block in the server configuration.
After a migration to a new server, that .htaccess file, or that Nginx block, doesn’t come along automatically. On Apache, resaving Settings > Permalinks regenerates the .htaccess and is usually enough. On Nginx, the server block has to be edited directly, which WordPress can’t do on its own.
Custom post types, used by many WooCommerce extensions and by page builders for their templates, need their own rewrite rules regenerated too: re-saving permalinks does this, but only if the plugin registering them is active at that moment. A mismatch between the siteurl/home options and the real domain after migration produces a different kind of 404 or redirect loop, unrelated to permalinks: the two look similar to a merchant but are fixed differently.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Related pages
Describe your need in one minute
A few targeted questions so I can reply with an estimate rather than another questionnaire.