Links and redirects checks
Triggers and fixes for broken, redirected and nofollow links, external links, redirect chains and loops, and JavaScript redirects.
Link issues are reported on the page that contains the link, so the fix is on that page (or the template, menu or component that renders the link). Redirect issues are reported on the redirecting URL. Only JS_REDIRECT is recheckable; the rest need a full audit, because they depend on other URLs of the site.
SEOFix reads links from <a href> elements. A link is internal when it points to the audited host, with or without www. Links under /cdn-cgi/ (Cloudflare's reserved path) are ignored.
Internal links
BROKEN_INTERNAL_LINK — Broken internal link
- Severity: error. Recheckable: no (needs a full audit).
- Trigger: the page links to an internal URL that was crawled and answered
4xxor5xx, or could not be fetched. Firewall-blocked targets are not counted. One issue per linking page and target. - Details:
broken_url,status_code(nullwhen the fetch failed). - Why it matters: links to missing pages waste crawl budget, leak link equity and send visitors to errors.
- How to fix: update the link to the correct URL, or remove it. If many pages link to the same
broken_url, the link is in a shared template, menu or footer; fix it there. If the target should exist, fix the target (seeBROKEN_PAGE).
REDIRECTED_INTERNAL_LINK — Internal link goes through a redirect
- Severity: notice. Recheckable: no (needs a full audit).
- Trigger: the page links to an internal URL that answered
3xx. - Details:
to_url(the linked URL),redirect_to(where it redirects). - Why it matters: each redirect adds latency and loses a little link equity.
- How to fix: change the link to point directly at the final URL. The most common causes are
http://links, missing or extra trailing slashes, and links to old paths.
<!-- before: /jobs redirects to /jobs/ -->
<a href="/jobs">Jobs</a>
<!-- after -->
<a href="/jobs/">Jobs</a>
NOFOLLOW_INTERNAL_LINK — Nofollow internal links
- Severity: notice. Recheckable: no (needs a full audit).
- Trigger: the page has at least one internal link whose
relcontainsnofollow. One issue per linking page. - Details:
count(distinct internal targets linked with nofollow),samples(up to 5). - Why it matters:
rel="nofollow"on links to your own pages stops link equity flowing to them. - How to fix: remove
rel="nofollow"from links to your own pages. If the goal was to keep a page out of search, usenoindexon that page; to stop crawling, userobots.txt.
External links
External links are probed in full audits only, after the crawl: up to 500 distinct external URLs per audit, one request at a time per host and at least 0.5 seconds apart.
BROKEN_EXTERNAL_LINK — Broken external link
- Severity: error. Recheckable: no (needs a full audit).
- Trigger: the page links to an external URL that answered
4xxor5xx, or failed to connect (not a timeout). One issue per linking page. - Details:
broken_url, plusstatus_codeorerror. - Why it matters: links to dead pages hurt user experience and how much search engines trust the page.
- How to fix: update the link to a working URL (the page's new location, or an archived copy), or remove it. Some sites answer
403or429to all automated requests; open the link in a browser before removing it.
EXTERNAL_REDIRECT — External link redirects
- Severity: notice. Recheckable: no (needs a full audit).
- Trigger: the page links to an external URL that answered
3xx. At most 50 issues per external URL. - Details:
external_url,status_code,redirect_to,linking_pages(all pages linking to it). - Why it matters: an extra hop for visitors, and often a sign the target moved.
- How to fix: when the redirect stays on the same host (only
httptohttpsor a path change), change the link toredirect_to. When it goes to another host, check the destination is still what you want to link to (it may be a parked domain or a login wall) and update or remove the link.
EXTERNAL_TIMEOUT — External link timed out
- Severity: notice. Recheckable: no (needs a full audit).
- Trigger: the request to the external URL timed out. At most 50 issues per external URL.
- Details:
external_url,error,linking_pages. - Why it matters: the linked site may be down, slow, or throttling bots.
- How to fix: open the link in a browser. If the site is gone or consistently slow, replace or remove the link; otherwise ignore it.
Redirects
REDIRECT_CHAIN — Redirect chain
- Severity: warning. Recheckable: no (needs a full audit).
- Trigger: from this URL it takes two or more redirects to reach a URL that does not redirect, following the redirects SEOFix crawled (up to 10 hops).
- Details:
chain, the list of URLs from this URL to the last one. - Why it matters: each hop slows the page and loses link equity; search engines may stop following long chains.
- How to fix: redirect the first URL straight to the final destination in one hop, and update links to point at the final URL. Chains often come from stacking rules, such as
http→https, then apex →www, then adding a trailing slash. Combine them into one rule.
# one hop from any http or apex URL to the canonical https://www host
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
REDIRECT_LOOP — Redirect loop
- Severity: error. Recheckable: no (needs a full audit).
- Trigger: following the redirects from this URL comes back to a URL already in the chain.
- Details:
chain, ending with the repeated URL. - Why it matters: the URL never reaches a page, so neither visitors nor crawlers can open it.
- How to fix: break the loop so the URL redirects once to a final
200page. Loops usually come from two rules that undo each other (adding and removing a trailing slash, or a CDN forcinghttpswhile the origin forceshttp).
JS_REDIRECT — JavaScript / meta refresh redirect
- Severity: warning. Recheckable: yes.
- Trigger: a 200 HTML page redirects in the browser to another URL, by either:
<meta http-equiv="refresh" content="N; url=...">with a target (a plain reload without a URL is not flagged), or- a small inline script (up to 1,000 characters, among the first 50 inline scripts) that assigns a literal URL to
locationorlocation.href, or callslocation.replace("...")orlocation.assign("..."), onwindow,document,top,selfor as a statement on its own.
- Details:
type(meta_refreshorscript),target. - Why it matters: client-side redirects are slower, not always followed by crawlers, and pass ranking signals less reliably than a server redirect.
- How to fix: replace it with a server-side
301redirect from this URL totarget, then remove the meta tag or script.
<!-- before -->
<meta http-equiv="refresh" content="0; url=https://example.com/new-page">
# after: the server answers the old URL with
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page
Related
More in Issue reference
Still stuck? Email [email protected] with your site and what you expected to see.