BIPIDA BLOG / WordPress migration
How to Fix Broken Links After a WordPress Migration
Fix broken links after a WordPress migration by checking HTTP status, permalinks, rewrite rules, stale domains and paths, redirects, internal links, and CDN caches.
Broken links after a WordPress migration are usually caused by a rewrite configuration that did not move with the site, stale domains or directory prefixes stored in content, or redirects that no longer match the public URL structure. The right repair depends on whether every pretty URL fails or only a known subset does.
Quick answer: Test one failing URL with curl -I, record every redirect and the final status, and compare it with a working URL. If all posts fail while the homepage works, verify the permalink structure and web-server rewrite configuration. If only selected links fail, find stale hosts, subdirectory prefixes, renamed slugs, or missing content. Redirect a genuinely moved URL to its closest replacement with a permanent redirect; let truly removed content return 404 or 410.
Classify the failure before editing anything
Choose one exact URL from a real page, menu, search result, or log entry. Test both the link as written and its final destination:
curl -I https://www.example.com/sample-page/
curl -IL --max-redirs 10 https://www.example.com/sample-page/
Record the status, Location headers, hostname, scheme, path, and whether the response body is a WordPress 404 page, a proxy error, or unrelated content. Keep a copy of the current web-server and redirect configuration before changing it.
Use the failure pattern to narrow the cause
- Homepage works but every post returns 404: permalink or rewrite configuration is the primary suspect.
- Only old-domain links fail: stored URLs, DNS, virtual host, or migration redirects need review.
- Only one content type fails: its post-type or taxonomy rewrite registration may be absent or changed.
- Only media fails: inspect file transfer, upload paths, and delivery using the missing-images guide.
- Links alternate between HTTP and HTTPS or
wwwvariants: canonical redirects or proxy scheme detection may conflict. - The response cycles through several URLs: diagnose a redirect chain or loop before touching permalinks.
Verify WordPress URL and permalink settings
Check the WordPress Address, Site Address, and permalink structure against the intended public URL. With WP-CLI, read them without changing state:
wp option get home
wp option get siteurl
wp option get permalink_structure
A site installed in a subdirectory can legitimately have different home and siteurl values. Do not force them to match until you understand the deployment. Also check whether configuration constants or environment-specific bootstrap code override the database values.
Repair rewrite rules at the correct layer
WordPress turns pretty URLs into internal queries through rewrite rules. The official wp rewrite flush documentation describes rebuilding those rules. First preserve the current configuration and confirm that required themes and plugins are active, because custom post types register their routes during runtime.
wp rewrite flush
Flushing updates WordPress rewrite rules; it does not repair an incorrect Nginx server block, a missing Apache module, a stale proxy route, or a nonexistent page. Repeating it after every request is not a fix.
Distinguish Apache from Nginx behavior
On Apache, verify that the virtual host allows the intended override and that the WordPress rewrite block is present in the correct document root. Preserve unrelated security and application rules when restoring it. A hard WP-CLI flush can update .htaccess only in supported single-site conditions and with the required server configuration.
Nginx does not use .htaccess. Its route fallback belongs in the managed server configuration, and WordPress cannot rewrite that file itself. The official WordPress Nginx guide explains this distinction. Validate and reload Nginx through the deployment's established workflow rather than pasting an Apache rule into it.
Check subdirectory and path-prefix changes
A move from /wordpress/ to the domain root, or the reverse, can leave links with an obsolete prefix. Compare the requested path with the new routing base, menu URLs, canonical tags, and generated assets. Confirm that the reverse proxy is not adding or removing the same prefix twice.
Use explicit redirects for public URLs that moved. Avoid broad regular expressions until representative paths, query strings, encoded characters, and excluded administrative routes have been tested.
Find stale domains safely
Old hosts can remain in post content, navigation, widgets, theme settings, page-builder data, or serialized plugin options. Start with a serialization-aware dry run:
wp search-replace 'https://old.example' 'https://new.example' --all-tables-with-prefix --dry-run
Review the tables and match count before any write. Search HTTP, HTTPS, www, staging hosts, escaped URLs, and path-only prefixes separately. Do not run raw SQL replacement over serialized values. The domain-migration guide covers the wider DNS, TLS, canonical, and replacement workflow.
Use redirects only when a resource moved
A previous URL with a clear replacement should normally receive a server-side permanent redirect to that specific destination. Keep the path short: old URL, at most a necessary canonical hop, then the final 200 page. Update internal links so regular visitors and crawlers do not depend on the redirect.
Google's redirect guidance recommends permanent redirects for lasting URL changes. Do not redirect every missing URL to the homepage; an unrelated destination can be interpreted as a soft 404 and gives users no useful answer.
Return honest status codes for removed content
If a URL never existed or was intentionally removed without an equivalent replacement, return a real 404 or 410. A custom 404 page can offer navigation, but its HTTP response must still be correct. Google's crawl-error guidance distinguishes missing pages from moved pages and warns against soft-error responses.
Before declaring a page removed, check for capitalization changes, trailing-slash policy, percent encoding, language prefixes, dates, category bases, and imported draft or private status.
Diagnose redirect loops methodically
List each hop and identify which layer generated it: CDN, load balancer, web server, security plugin, WordPress, or application code. Common loops include HTTP-to-HTTPS at the edge followed by HTTPS-to-HTTP in WordPress, competing www rules, and duplicate trailing-slash normalization.
Fix HTTPS detection and trusted proxy headers at the appropriate boundary. Never disable TLS enforcement globally just to hide a loop. Change one redirect owner at a time and keep a rollback copy.
Check custom post types, taxonomies, and plugins
If standard posts work but products, portfolios, courses, or localized routes fail, confirm that the plugin or theme registering those routes is active and compatible. Compare its slug and rewrite settings with the source site. Flush rules once after restoring the registration; a flush performed while the component is inactive cannot recreate its routes.
For multilingual sites, test each language prefix and confirm that links remain in the intended language. For multisite, verify network paths, mapped domains, and per-site routing rather than applying a single-site assumption.
Update internal links and navigation
Even a correct redirect map should not become the site's permanent internal-link architecture. Update links in post content, menus, reusable blocks, widgets, page-builder templates, breadcrumbs, XML sitemaps, and structured navigation where those systems store explicit URLs.
Start with high-traffic pages and navigation. The SEO-safe migration guide explains how crawl comparison, canonical checks, and sitemap review fit into post-migration validation.
Account for caches and CDN behavior
A CDN or reverse proxy may cache redirects and 404 responses. Compare the public response with an authorized origin test, inspecting Age, cache-status, and Location headers. Purge one affected URL first and verify the result before a broader invalidation.
Also clear only relevant application or page caches after the underlying route is fixed. Cache clearing cannot create a missing rewrite rule or restore deleted content.
Validate the repair with a controlled crawl
- Retest the original failing URL without relying on a browser cache.
- Test a post, page, category, pagination URL, search page, media URL, and any custom content type.
- Verify HTTP/HTTPS, preferred host, trailing-slash behavior, and language prefixes.
- Crawl internal links and classify remaining 3xx, 4xx, 5xx, chains, and loops.
- Compare important old URLs with the redirect map and confirm final destinations.
- Review access logs and search-platform reports over time; historical errors do not disappear instantly.
Common mistakes
- Saving permalinks repeatedly without checking the web server
- Replacing serialized URLs with raw SQL
- Redirecting every 404 to the homepage
- Stacking CDN, server, plugin, and WordPress redirects for the same rule
- Ignoring custom post types, language prefixes, or multisite paths
- Purging every cache before proving which layer is stale
- Changing slugs to solve a routing problem
When specialist migration help is appropriate
A large redirect inventory, multisite network, multilingual routing, custom content types, or several proxy layers makes bulk repair risky. A controlled WordPress migration service can compare old and new URL sets, isolate the failing layer, and validate redirects before a limited change is applied.
Frequently asked questions
Why does the homepage work while every post returns 404?
The public server is reachable, but pretty-URL rewrites may be missing, disabled, or pointed at the wrong document root. Verify the permalink structure and the correct Apache or Nginx configuration.
Does saving the Permalinks screen always fix migration 404s?
No. It may refresh WordPress rules, but it cannot repair an Nginx server block, an inactive custom-post-type plugin, a wrong proxy prefix, or content that does not exist.
Should every old 404 redirect to the homepage?
No. Redirect a moved URL to its closest relevant replacement. Return a genuine 404 or 410 when no equivalent resource exists.
Why does a fixed link still show the old redirect?
A browser, page cache, reverse proxy, or CDN may retain the previous response. Compare headers at each layer and invalidate the narrowest relevant cache after confirming the origin is correct.
YOUR NEXT STEP
Need help with this issue?
Share the symptoms and what you have already tried in a support request.
Open a support ticket