DEV Community

Sandeep Singh
Sandeep Singh

Posted on

404 Errors After a Site Migration or Redesign: A Recovery Checklist

The new site launches. It looks better, it's faster, the team is happy. Then, a week or two later, someone notices: organic traffic is down, a few customers have emailed about "page not found" errors, and the Search Console Page indexing report shows a growing pile of 404s.

This is the most common way a redesign or platform migration goes wrong. The new pages are fine. The problem is that the old URLs, the ones Google, other websites, bookmarks, old newsletters and social posts all point to, now go nowhere. Every one of those is a visitor who arrived with intent and left with an error page.

The good news is that this is usually recoverable. Below is the checklist I'd work through, in order, whether you moved from WordPress to a headless setup, changed your Shopify theme and URL handles, or just reorganised your blog's categories.

First: what Google actually says about 404s

It helps to know what you're fixing, and what you're not.

Google's own Search Central blog is clear that 404s on their own aren't a penalty: "If some URLs on your site 404, this fact alone does not hurt you or count against you in Google's search results", and those 404s don't affect how your other working URLs perform (Do 404 errors hurt my site?). Google's HTTP status documentation adds that when a previously indexed URL returns a 4xx, "the indexing pipeline removes the URL from the index" (HTTP status codes).

Put those together and the real cost of migration 404s is clear:

  1. Pages that used to rank drop out of the index, and the new equivalents have to earn their place from scratch instead of inheriting the old URL's signals.
  2. Links from other sites now point to dead pages, so the value of those links, and the referral traffic they bring, is lost.
  3. People who click hit a dead end. That's the immediate, measurable loss: leads, sales, sign-ups, readers.

So the goal isn't "zero 404s". It's every old URL that had value now lands on its correct new home in one step, and anything genuinely gone returns an honest 404 or 410.

Step 1: Rebuild the list of old URLs

You can't redirect what you can't list. If you didn't save a crawl before launch (most people don't), reconstruct it from several sources, because each one sees different URLs:

  • Search Console → Indexing → Pages → Not found (404). Export the examples. These are URLs Google knows about that now fail.
  • Search Console → Performance. Set the date range to before the migration and export the top pages. These are the URLs that were actually earning clicks, so they're your priority list.
  • Search Console → Links → Top linked pages. URLs other sites link to.
  • Your analytics tool. Landing pages from the months before launch.
  • The old sitemap, if you still have it, or the Wayback Machine's capture of it.
  • Server or CDN logs showing 404 responses since launch, if you have access.
  • Your own old content: newsletters, social posts, PDFs, documentation and email templates that hard-coded links.

Combine these into one spreadsheet, remove duplicates, and keep a column for where each URL came from.

Step 2: Check each old URL's current status

Run the whole list through a crawler in list mode. Screaming Frog SEO Spider does this in Mode → List (free up to 500 URLs; limits). For a quick script:

while read -r url; do
  printf '%s\t%s\n' "$url" "$(curl -s -o /dev/null -w '%{http_code} %{num_redirects} %{url_effective}' -L "$url")"
done < old-urls.txt > status.tsv
Enter fullscreen mode Exit fullscreen mode

That gives you the final status, the number of redirect hops and the final URL for each one. Sort into buckets:

  • 404/410: needs a redirect, or confirmation it's really gone
  • Redirects to the homepage: probably wrong (see below)
  • 2+ hops: works, but slow and should be flattened
  • 200 at the right place: done

Step 3: Map old URLs to new URLs

Google's site move guide calls this step out explicitly: "Prepare a URL mapping from the current URLs to their corresponding new format" (Site moves with URL changes). For each old URL, decide:

  • Same content, new address → 301 to the new URL.
  • Content merged into another page → 301 to the page that now covers it.
  • Content deliberately removed, no equivalent → let it return 404 or 410. Google's guide says that for deleted or merged content, make sure "those URLs correctly return an HTTP 404 or 410 error response code".

Look for patterns. Migrations usually change URLs systematically, such as /blog/2023/05/post-name/ becoming /posts/post-name, or /products/ becoming /shop/. One pattern-based rule can cover hundreds of URLs. Handle the exceptions individually.

Don't redirect everything to the homepage

It's tempting to catch every unknown URL and send it to /. Google warns against exactly this: a site that "redirects any unknown URLs to their home page instead of returning 404 errors" is treated as a soft 404 case, which "can have negative effects on our understanding and indexing" of the site (Do 404 errors hurt my site?). It's also bad for visitors, who land on the homepage with no idea why. Redirect to a genuinely relevant page or return an honest 404 with helpful navigation.

Step 4: Implement redirects properly

  • Use permanent, server-side redirects (301 or 308) for moved content. Google's redirect documentation explains that permanent redirects signal the target should be shown in search results, while temporary ones (302, 307) keep the old URL (Redirects and Google Search). Server-side redirects are the most reliably understood; JavaScript redirects are a last resort.
  • Redirect in one hop. If the old site already had redirects, update them to point straight at the final URL. Each hop adds a network round trip, which Lighthouse says can delay loading "by hundreds of milliseconds", and it fails pages with two or more redirects (Lighthouse: Avoid multiple page redirects).
  • Use your platform's redirect tool: Shopify's URL redirects, WordPress's Redirection plugin, _redirects files on static hosts, or rules at your web server or CDN.
  • Keep them. Google recommends keeping redirects "for as long as possible, generally at least 1 year", and suggests that from users' perspective you consider keeping them indefinitely.

If you moved to a new domain, also submit a Change of Address in Search Console for the old site. Google says this is only needed for domain or subdomain changes, not for HTTP→HTTPS or path changes within the same domain.

Step 5: Fix internal links at the source

Redirects rescue external traffic. Your own site shouldn't depend on them. After a migration it's common for menus, footers, in-content links, related-post widgets and image references to still point at old URLs, especially if content was imported with hard-coded absolute links.

Crawl the new site and check:

  • Internal links returning 4xx (fix the link)
  • Internal links that redirect (update them to the final URL)
  • Images returning 404 (re-upload or fix paths, as media paths often change in migrations)
  • Links still pointing at the staging domain

I walked through doing this on a store in How to Find and Fix Broken Links on a Shopify Store. The same approach works on any platform.

Step 6: Check the things migrations quietly break

  • noindex left on from staging. It's the classic launch-day mistake. View source on key templates.
  • robots.txt still blocking everything.
  • Canonical tags pointing at old or staging URLs.
  • HTTPS and mixed content: new templates loading old http:// assets.
  • Sitemap: make sure the new sitemap lists only new, working URLs, and submit it in Search Console.
  • Titles and meta descriptions that didn't migrate and fell back to a template default.

If your site is small, SEO Health Basics for Personal Websites and Portfolios covers how to check each of these quickly.

Step 7: Confirm the recovery

  • Re-run your old URL list from Step 2. Every URL should now be either a single-hop 301 to the right page or a deliberate 404/410.
  • Use URL Inspection in Search Console on your most important old and new URLs.
  • Watch the Page indexing report. The count of "Not found (404)" URLs Google reports may take a while to change because Google recrawls old URLs gradually. What matters is that the URLs you care about are redirected correctly.
  • Compare Performance data for your top pre-migration pages against their new URLs over the following weeks.
  • Watch referral traffic from sites that linked to you.

Be patient with search recovery. Google has to recrawl old URLs to see the redirects, and that happens over time, not overnight.

Step 8: Keep watching

The weeks after a migration are when new problems appear: a redirect rule gets overwritten by a plugin update, a CMS editor changes a slug, an image CDN path changes. A one-off audit catches what's broken today. Ongoing monitoring catches what breaks next week.

Disclosure: I build Uchik, which is meant for that ongoing part. Uchik crawls your site every day with read-only requests and emails a report of broken links, missing images, redirect chains and loops, and HTTPS problems, each with the page and HTML element that caused it. How it works explains how it follows redirects hop by hop, the features page lists every check, and the sample report shows what a redirect-chain finding looks like. It checks the HTML the server sends, so links added only by JavaScript may be missed, and it crawls the live site rather than your old URL list, so Step 2 still needs a list-mode check. You can sign up for free.

The checklist

  • [ ] Old URL list rebuilt (Search Console, analytics, old sitemap, logs, backlinks)
  • [ ] Every old URL's current status checked
  • [ ] Old → new URL map built, using patterns where possible
  • [ ] No blanket redirects to the homepage
  • [ ] Permanent, server-side, single-hop redirects in place
  • [ ] Change of Address submitted (domain moves only)
  • [ ] Internal links, images and menus updated to final URLs
  • [ ] No stray noindex, robots.txt blocks or staging canonicals
  • [ ] New sitemap submitted
  • [ ] Old URL list re-checked after the fix
  • [ ] Ongoing monitoring in place for the months after launch

A migration doesn't end at launch. It ends when every link people relied on still takes them somewhere useful.

Top comments (0)