You migrated from old.com to new.com. Set up a redirect from old.com → new.com. Tested the homepage — works. Two weeks later, Search Console shows hundreds of 404s on the new domain, traffic dropped, and external backlinks now go nowhere. The bug: you redirected the root, not the URL patterns. old.com/blog/article resolves to new.com/blog/article, but if that URL doesn’t exist on the new domain (because you also reorganized URL structure), it 404s. Every deep URL needs a redirect mapping, and the mapping might not be a simple 1:1.
This guide walks through building a complete redirect map and verifying it post-deploy.
Common causes
Ordered by hit rate, highest first.
1. Only root domain redirected, deep URLs unhandled
old.com → new.com redirects the bare root. old.com/blog/article-name follows the redirect, lands at new.com/blog/article-name — but that URL might not exist on the new site. 404.
How to spot it:
curl -sI "https://old.com/some-deep-url" | head -3
If you see Location: https://new.com/, only root is redirected. Should Location: https://new.com/some-deep-url.
2. URL structure changed but redirect map doesn’t follow
You restructured from /blog/article-name to /articles/article-name during the migration. Even with full URL redirects, they go to the old path on the new domain. 404.
How to spot it: Check redirect destinations. If they preserve old paths but old paths don’t exist on new site, you need a path rewrite as part of the redirect.
3. Wildcard / pattern redirect not working
You wrote a pattern redirect but the platform doesn’t support the syntax. Falls back to no redirect.
How to spot it: Vercel vercel.json redirect with :slug* — make sure pattern is valid. Test with curl.
4. Hosting platform has redirect count limit
Vercel has a 1024 redirect limit in vercel.json. Netlify _redirects has a higher but finite limit. Beyond that, redirects silently don’t apply.
How to spot it: Count redirects in your config. If > 1024, some are being dropped.
5. Old domain’s hosting is fully decommissioned
If you completely shut down old.com’s hosting (not just DNS), the redirect can’t fire. Old URLs return connection refused / nothing.
How to spot it: curl -I https://old.com/anything returns network error. Need to keep redirect-only hosting running.
6. HTTPS old domain has no cert
You set up HTTP redirect but HTTPS request to old.com fails with cert error before redirect can fire. Modern browsers default to HTTPS.
How to spot it: curl -I https://old.com/ returns cert error. curl -I http://old.com/ works. HSTS-aware browsers can’t reach the http version.
Shortest path to fix
Step 1: Export ALL old URLs
Sources:
old.com/sitemap.xml(if archived)- Search Console (old domain still verified) → Performance → Pages → export
- Server logs from old hosting
- Wayback Machine for unindexed pages
- Any backlinks data (Ahrefs, Majestic, GSC links report)
Step 2: Build the redirect map
For each old URL, decide:
- Direct equivalent:
old.com/blog/foo → new.com/articles/foo - No exact match: redirect to nearest category —
old.com/topic-x/* → new.com/category/x/ - Truly orphaned: redirect to homepage as last resort
CSV format works:
old_path,new_path
/blog/article-name,/articles/article-name
/topics/ai,/category/ai
/old-broken-page,/
Step 3: Convert to platform redirect syntax
Vercel — vercel.json:
{
"redirects": [
{ "source": "/blog/:slug", "destination": "https://new.com/articles/:slug", "permanent": true },
{ "source": "/topics/:topic", "destination": "https://new.com/category/:topic", "permanent": true },
{ "source": "/:path*", "destination": "https://new.com/:path*", "permanent": true }
]
}
Order matters — specific patterns before catchall.
Netlify — _redirects:
/blog/* /articles/:splat 301
/topics/* /category/:splat 301
/* /:splat 301
Firebase — firebase.json:
{
"hosting": {
"redirects": [
{ "source": "/blog/:slug", "destination": "https://new.com/articles/:slug", "type": 301 }
]
}
}
Step 4: Deploy redirects on the OLD domain’s hosting
Keep old.com’s hosting running with just the redirect rules. You don’t need full app — just a redirect-only deployment. Vercel/Netlify can host a static “site” that’s only the redirect config.
Make sure the old domain still has DNS pointing to this redirect host AND a valid SSL cert.
Step 5: Verify with curl
Sample 50 random old URLs:
for url in $(head -50 old_urls.txt); do
result=$(curl -sI "$url" | head -1)
location=$(curl -sI "$url" | grep -i location | head -1)
echo "$url → $result $location"
done
Every result should be 301 with Location: pointing to a real new URL.
Step 6: Submit Change of Address in Search Console
Old domain verified in Search Console → Settings → Change of address → declare move to new domain. Helps Google understand the move.
Step 7: Keep redirects forever
Don’t take them down after a year. External backlinks may persist for years. Keep the redirect-only deployment indefinitely.
When this is not on you
Hosting platforms have different redirect syntax: Vercel vercel.json, Firebase firebase.json, Netlify _redirects. Use the right syntax for your platform; copy-pasting from another can silently fail.
Easy to misdiagnose as
People assume Google “figures it out.” Without explicit 301s, link equity is lost permanently. Google does NOT guess that old.com/foo should equal new.com/foo if URL structure changed.
Prevention
- Build the redirect map BEFORE launching the new domain, not as cleanup after.
- Keep redirect rules in source control (
vercel.json,_redirects, etc.). - Maintain the old-domain redirect deployment indefinitely; never take it down.
- After deploy, sample test 50+ redirects via
curl. - For massive sites, plan a redirect strategy that uses wildcards efficiently to stay under platform limits.
FAQ
- How long to keep redirects? Forever. At minimum 12+ months for SEO equity, but ideally indefinitely for external backlinks.
- Do 302s work for permanent moves? No — use 301. 302 doesn’t transfer SEO value.
Related
- Indexing coverage drop after redesign
- Canonical still uses old domain
- Sitemap references old domain
- Search Console property mismatch new domain
Tags: #Domain #DNS #SSL #Troubleshooting #Redirect