All posts

How to Audit Redirects After a Website Migration

··3 min read

After a migration, every old URL should reach its new page in a single permanent redirect, and that page should answer 200. Paste your old URLs into the bulk redirect checker: each row lists every hop with its status code and the final URL, and flags loops, long chains, HTTPS-to-HTTP drops and pages that end in an error.

Check where a list of URLs redirects →

Check them in bulk

  1. Export the old URLs: from your old sitemap, your analytics' top landing pages, or the links in emails and ads you've already sent.
  2. Open the bulk redirect checker and paste them, one per line: up to 100 a run, or 500 after a free Google sign-in.
  3. Press Check redirects. Each URL is requested once and its redirects followed, up to ten hops.
  4. Read each row: OK, Redirects, Broken (the final page answers 4xx or 5xx), Loop, Too many hops or No answer.
  5. Filter to Broken and long chains, and download the CSV.

Do it by hand

One row per URL: hops, final status and where it landed.

printf "http://stripe.com/docs\nhttps://docs.github.com/en/github\nhttp://python.org\nhttps://github.com/nope-1109-zz\n" > old-urls.txt

while read -r u; do
  curl -s -o /dev/null -m 10 -L -w "$u,%{num_redirects},%{http_code},%{url_effective}\n" "$u"
done < old-urls.txt
# http://stripe.com/docs,2,200,https://docs.stripe.com/
# https://docs.github.com/en/github,1,200,https://docs.github.com/en
# http://python.org,1,200,https://www.python.org/
# https://github.com/nope-1109-zz,0,404,https://github.com/nope-1109-zz

Every hop of one URL, with its status code:

curl -sL -m 15 -o /dev/null -D - http://stripe.com/docs | grep -iE '^(HTTP|location)'
# HTTP/1.1 301 Moved Permanently
# Location: https://stripe.com/docs
# HTTP/2 301
# location: https://docs.stripe.com
# HTTP/2 200

We ran these on 9 November 2026. Stripe's old docs URL takes two permanent hops: http to https, then the move to its docs subdomain. That's fine for one URL; if your own migration adds a hop on top of an existing http-to-https redirect, point the old URL straight at the final page instead.

Use GET, as above, rather than curl -I. On the same day, curl -sIL https://aka.ms/admin (HEAD requests) ended in a 500 while the same chain with GET ended in a 200. Some servers answer HEAD differently.

What to fix

  • 404 at the end. The old URL has no mapping. Add a redirect to the closest new page, not a blanket redirect to the homepage.
  • 302 or 307 where you meant permanent. RFC 9110, section 15.4 defines 301 and 308 as permanent and 302 and 307 as temporary, where "the client ought to continue using the original target URI for future requests." Use 301, or 308 if the request method must not change.
  • Chains. Old redirects from earlier migrations pile up. Point each old URL directly at its final destination.
  • Loops. A rule that sends a URL back to one already visited. Browsers give up with an error.
  • HTTPS to HTTP. A hop that drops to plain http, usually a hard-coded rule from the old site.

For just the home pages of many domains, use the bulk website status checker; for the http, https, www and non-www versions of one domain, the WWW redirect checker.

Next step: check the list you'll announce the new site to

A migration announcement goes to your whole list, including addresses that died since the last big send. Upload it at /verify to check every mailbox without sending. The first 100 checks are free with a Google sign-in, no card.

Pro, $39 a month: Unlimited email verification.* Never metered, never cut off. See pricing.

*Fair use: the first 100,000 checks a month at full speed, then slower, never cut off.

More: check if a list of websites is online, do URL shorteners hurt email deliverability?

Common questions

How do I check redirects for a list of URLs?

Paste the URLs into the bulk redirect checker, one per line. It follows each one's redirects up to ten hops and shows every status code, the final URL and whether it ended in an error, with a CSV.

Should a migration use 301 or 302 redirects?

Permanent ones: 301, or 308 if the request method must not change. RFC 9110 defines 302 and 307 as temporary, meaning the client ought to keep using the original URL.

Why does curl show a different result from my browser?

Sites can answer differently by country, device, cookies or bot protection, and some redirect with JavaScript or a meta refresh that curl and the redirect checker don't follow. Open the URL in a browser to confirm.

How many redirect hops are too many?

The bulk redirect checker flags chains of more than three hops as long and stops at ten. After a migration, each old URL should need one.

Check your list before you send

Real mailbox checks over SMTP, and nothing is sent to the address. Sign in with Google and your first 100 email checks are free, no card. Plans for bigger lists are on the pricing page.