SEO Checks · Technical
Internal links & redirect chains: what we check and how to reproduce it
Quick answer: Our engine runs two checks here. The redirect chain check runs on every audit, including the free one: it counts the redirects between the URL it requests and the page that answers, and warns at 3 or more. The broken internal links check needs a full-site crawl, because it has to request every page your links point to. The free audit does not test your links. The snippet below does, for any page on your own site.
Why these two things matter
Google's link guidelines say that every page you care about should have a link from at least one other page on your site, and that Google can only crawl a link if it is an <a> element with an href. An internal link that ends in a 404 is a crawl path that leads nowhere, and a dead end for the person who clicked it.
For redirects, Google's HTTP status code documentation says its crawlers follow up to 10 redirect hops by default, and that the content of a redirecting URL is ignored in favour of the final target. A chain therefore rarely stops Google outright. What it costs is one extra HTTP request per hop, made in sequence, before the browser receives a single byte of the page. Long chains usually come from layered fixes: an http-to-https rule, then a www rule, then a CMS redirect for a renamed page, each added at a different time.
Check 1: Redirect chain length
ID: technical-redirect-chain-length
Severity: Warning
Runs in: the free audit (for the URL you enter) and the full crawl (for every crawled page)
The rules, read from the engine source and tested against a local server:
- What counts as a hop: every 3xx response that carries a
Locationheader. The URL you entered is not a hop. A chain/a → /b → /c → /dis 3 hops. - Pass: 0, 1 or 2 hops. Warning: 3 or more. The report lists every URL in the chain, in order, so you can see which rule added which hop.
- Relative redirects (
Location: new-page) are resolved against the URL that sent them, as a browser would. - A 3xx without a
Locationis treated as the final response, not as a redirect. - Loops: the engine follows up to 10 redirects. If the 11th response is still a redirect, the free audit stops with Too many redirects and no report, because there is no page to audit.
- Where it starts: a bare domain is requested as
https://. If your site sendshttp://tohttps://and then towww, the free audit sees only the last hop. Enter thehttp://address to measure the full chain. The http hop is also tested on its own by the HTTP-to-HTTPS check (see HTTPS explained). - In a full crawl, a chain that leaves your domain stops at the first off-site URL. The crawl does not follow it to the other site.
In the 62 free audits of 52 third-party sites run up to 4 October 2026, none failed this check: 60 met no redirect at all and 2 met one. But 61 of those 62 audits started at an https:// address, and 9 of the 52 sites failed the separate HTTP-to-HTTPS check. The chains that begin at http:// were almost never walked from the start. Treat a pass on a bare domain as a pass for the https entry point only.
Check 2: Broken internal links
ID: technical-internal-link-status
Severity: Critical
Runs in: full-site crawl only. The free audit fetches only the URL you enter, so it doesn't test the links on it.
- Which links:
<a href>elements in the HTML as served. Links that JavaScript adds after the page loads are not seen. The#fragmentis dropped and common tracking parameters such asutm_sourceare removed before comparing URLs. - What counts as internal: the same registrable domain, so a link from
example.comtoblog.example.comis internal. - Broken: the final status after redirects is 4xx or 5xx, or there was no response at all (reported as status 0). A link to a URL that redirects to a 404 is listed under the URL you linked to, with the 404.
- Only crawled targets are tested. A crawl visits up to 50 pages by default. A link to a page outside that set has no status and is not counted either way, which is why a pass reads "no crawled internal links returned 4xx/5xx".
- The report shows each broken link's URL, its anchor text and the status code, per page.
Orphan pages, click depth and links per page are crawl checks too, covered in Link health explained.
Reproduce what our checker saw
Count the redirect hops
This sends the same user-agent as our checker and prints the number it compares against 2:
curl -sL -o /dev/null -A 'SEOCheckerBot/1.0 (+https://seoanalysischecker.com/bot)' \
-w '%{num_redirects} redirects -> %{url_effective} (%{http_code})\n' \
http://example.com/To see each hop and which status code produced it:
curl -sL -D - -o /dev/null http://example.com/ | grep -iE '^(HTTP/|location:)'
If curl and your report disagree, the server is probably answering differently by user-agent, country or cookie. Run the first command with and without -A to check.
Test the links on one page
Run this in the browser console on any page of your site. It reads the page's HTML as served and applies the same rule as check 2 to every link on the same origin:
const html = await (await fetch(location.href)).text();
const doc = new DOMParser().parseFromString(html, 'text/html');
const urls = [...new Set([...doc.querySelectorAll('a[href]')]
.map(a => { try { const u = new URL(a.getAttribute('href'), location.href); u.hash = ''; return u; } catch { return null; } })
.filter(u => u && u.origin === location.origin).map(String))];
let broken = 0;
for (const u of urls) {
const status = await fetch(u).then(r => r.status, () => 0);
if (status === 0 || status >= 400) { broken++; console.log(status, u); }
}
console.log(`${urls.length} links tested, ${broken} broken`);Browsers block reading responses from other origins, so links to subdomains are skipped here even though our crawl treats them as internal. For the same reason, a link that redirects to another origin prints status 0. Open those by hand before you treat them as broken. Each URL is requested once, so on a page with hundreds of links give it a moment.
How to fix what it finds
Long redirect chains
- Point the first rule at the final URL. If
http://example.comgoes tohttps://example.comand then tohttps://www.example.com, one rule can send both straight tohttps://www.example.com. The platform steps are in the www/non-www guides for WordPress, Shopify and Webflow. - Collapse old redirects. When a page is renamed twice, change the first redirect to point at the newest URL instead of adding a second one.
- Link to the final URL. Internal links, canonical tags and sitemap entries should use the URL that answers 200, so nobody starts a chain at all.
Broken internal links
- The page moved: update the
hrefto the new URL, and add a 301 from the old one for links you don't control. - The page is gone for good: remove the link, or point it at the closest page that still exists.
- Status 0: the server didn't answer in time or refused the connection. Retry before you edit anything, because it may have been temporary.
Check your redirect chain
The free checker counts the redirects on the URL you enter, alongside its on-page, technical and AI-readiness checks. Enter the http:// address to measure the full chain. No signup required.
Check your site free →FAQ
How many redirects is too many?
Our checker counts the redirects between the URL it requests and the page that finally answers. Up to 2 pass; 3 or more is a warning. Google documents that its crawlers follow up to 10 redirect hops by default. One redirect from the old URL to the final URL is the cleanest setup.
Why did the free checker not report broken links?
Testing links means requesting every page they point to. The free checker audits only the URL you enter, so the broken-link check runs in a full-site crawl only. The console snippet on this page tests the links on any page of your own site.
My site redirects http to https to www. Why did the redirect check pass?
If you type a bare domain, the free checker starts at https://, so the http hop is never part of the chain it measures. That hop is tested separately by the HTTP-to-HTTPS check. Enter the http:// address to measure the whole chain.
A link points to a URL that redirects to a 404. Is it reported?
Yes. The crawl follows the redirect and records the final status against the URL in your link, so the report lists the link as you wrote it, with a 404.
Keep reading