Skip to content

SEOPart of: Broken links and status codes

Broken internal links: find them and fix them at the source

Broken internal links are links between your own pages that lead to a 404 or an error. Where they hide (menus, templates, content), how to find every copy, and how to fix them at the source so they stay fixed.

getReport teamUpdated 26 Sept 202612 min read

Broken internal links are links from one page of your site to another page of your site that no longer answers: the target returns 404 Not Found, 410 Gone or a server error. They are the broken links you control completely, so they are also the ones you can fix for good. This guide shows where they hide, how to find every copy, and how to fix them at the source (the menu, the template or the post) rather than one page at a time. It is part of the wider guide to finding and fixing broken links.

Quick answer

  • Start with templates: a broken link in the menu, footer or a sidebar widget is broken on every page. Run the broken link checker on your home page first.
  • Then the content: check your most visited pages, then old posts with many links.
  • For each broken target, decide what it should answer: restore it, 301-redirect it to the closest live page, or leave it 404 if it is truly gone.
  • Then edit every link to it so it points straight at the live URL. Search the CMS or source files for the old path to find every copy.
  • Watch relative links: href="pricing" without a leading slash resolves against the current folder and breaks on deeper pages.
  • Prevent new ones: search for a page's path before you rename or delete it, and add the redirect in the same step.

An internal link points from a page on your site to another page on the same site. It is broken when following it ends on an error: a 4xx such as 404 or 410, a 5xx server error, or no answer at all. It is the most common kind of broken link, and the only kind where both ends, the link and the target, are yours:

KindYou fix
Broken internal linkThe link and, if needed, the target
Broken backlinkOnly the target, with a redirect
Broken outbound linkOnly the link: replace or remove it
  • Visitors hit a dead end at the point where they wanted to go further: the size guide, the pricing page, the next step in a tutorial.
  • Crawlers waste fetches on URLs you do not want. On small sites this is minor; on shops with thousands of pages, broken links in faceted navigation or product templates add up to many requests.
  • Your internal linking weakens. Internal links tell Google which pages matter and how they relate; a link to a dead page tells it nothing, and the page that should have received the link loses it.

Google has said since its 2011 post "Do 404s hurt my site?" that 404s on some URLs do not hurt how the rest of the site ranks, so this is not about a penalty. It is about lost visitors and wasted signals, which 404 errors and SEO covers in more depth.

The same broken link can sit in one place and show on a thousand pages. Look in this order:

  1. Navigation and footer. Header menus, mega menus, footer columns and legal links appear on every page.
  2. Templates and blocks. "Related products", "Recent posts", breadcrumbs, author boxes, call-to-action banners, cookie-banner links to the privacy policy.
  3. Widgets and sidebars. Often set up once at launch and never checked again.
  4. Body content. Links inside posts, product descriptions and category texts, especially in old content.
  5. Generated links. Pagination, tag clouds, filters and search result pages, which can create links to pages that do not exist.

The usual causes

  • A URL changed without a redirect, after renaming a post, moving a product to another category or changing the permalink structure.
  • A page was deleted while other pages still link to it.
  • A typo in a hand-written link, or a link copied from a draft or preview URL.
  • A staging or development host left in links after launch, such as staging.example.com or localhost.
  • A relative link without a leading slash. On /blog/new-shoes/, the link href="pricing" resolves to /blog/new-shoes/pricing, which does not exist. Use /pricing/ or the full URL.
  • A migration that changed the URL structure and left old paths in content fields.

The broken link checker reads every <a href> on the page you enter and requests each unique URL, up to 100 on your own host and 50 to other sites. Servers that refuse HEAD requests get a short GET instead, redirects are followed to the final answer, and anything that answers 4xx, 5xx or nothing within eight seconds counts as broken. The links table shows the anchor text of each link, so you can find it in the editor, plus its status and where it redirects.

Run it on your home page first, which catches every broken menu and footer link at once. Then run it on one page per template: a product page, a category page, a blog post and a landing page. Then work through your most visited pages.

Check a list of URLs

The bulk URL checker takes up to 1,000 addresses and labels each one OK, redirect, redirect chain, not found, server error, noindex or unreachable. Paste the URLs in your sitemap, or every URL your CMS exports, and filter to "not found". Any of those that your pages link to is a broken internal link target.

Use what Google and visitors already found

  • Search Console → Indexing → Pages → "Not found (404)" lists URLs Google tried to crawl. Inspect an example URL: URL Inspection often shows the referring page, which is where the broken link lives.
  • Your server's access log records the Referer of requests that got a 404. A referrer on your own domain points straight at the page with the broken link.
  • A crawl of every page and link on the site is a funded unlock on getReport. Until then, the checks above, run on templates plus your key pages, find most broken internal links that matter.

Fix them at both ends: first decide what the dead target should do, then change every link to it.

1. Decide what the target should answer

The page …Do this
Moved to a new address301-redirect the old URL to the new one
Was deleted, with a close equivalent301 to the equivalent
Was deleted, with nothing to replace itLeave it 404 or 410 and remove the links
Was deleted by mistakeRestore it
Never existed (typo, wrong relative path)No redirect needed; fix the link

The redirect catches everything you do not control, such as bookmarks, other sites and Google's index. The 301 redirects guide covers the rules on each server and CMS, and 404 vs 410 vs redirect helps with the harder cases.

A redirect alone is not the fix for internal links. Each redirected link still costs the visitor a round trip, and chains build up over time. Edit the link itself so it points straight at the final URL. Find every copy by searching for the old path, not the full URL, so you catch relative and absolute forms alike.

WordPress. Menus are under Appearance → Menus or the Site Editor's Navigation block; widgets under Appearance → Widgets. For links in content, search the posts list for the old path. For many posts at once, WP-CLI can replace a URL across the database; always run it with --dry-run first and take a backup:

Shell
wp search-replace '/pricing-2020/' '/pricing/' --dry-run
wp search-replace '/pricing-2020/' '/pricing/'

Shopify. Menus are under Content → Menus in the admin (older admins: Online Store → Navigation). Links in theme sections are edited in the theme editor; links in products, collections and pages in their description editors.

Static sites and frameworks. Search the source and content folders, then rebuild:

Shell
grep -rn "/pricing-2020/" content/ src/

Hard-coded template links. Links in theme files need a developer or a theme update. Put them first on the list, since they appear on every page that uses the template.

A link that redirects still works, so the checker lists it separately, not as broken. Updating it is still worth a minute on internal links: it saves visitors a hop and keeps chains from forming. Internal links that redirect covers the search-and-replace in detail.

How to verify the fix

  • Re-run the broken link checker on the pages and templates you changed. Reports are cached for 12 hours, so use the "Re-run" link.
  • Paste the old target URLs into the bulk URL checker: moved pages show one 301 and then 200, removed pages show 404 or 410.
  • In Search Console, open "Not found (404)" and click Validate fix for the group. The count falls as Google recrawls, which can take weeks.
  • Before deleting or renaming a page, search your content and templates for its path. Fix the links and add the redirect in the same session.
  • Link with root-relative or full URLs, never with bare relative paths like pricing.
  • Use the CMS's own link picker instead of pasting URLs, where it has one: WordPress stores the link target by URL, but the picker at least prevents typos.
  • Check templates monthly and after every theme update, redesign or migration. The monthly site health routine includes it.
  • Give every important page several internal links, so one broken link does not cut it off. Internal links: how many, where and with what anchor text and orphan pages cover the linking side.

Common mistakes

  • Fixing one page when the link is in the template. Find where the link comes from before you edit.
  • Only adding a redirect. It stops the 404, but every internal link now costs a hop, and a later clean-up that deletes the redirect breaks them all again.
  • Redirecting a deleted page to the home page to make the broken link "work". Google treats it as a soft 404 and visitors land somewhere they did not ask for.
  • Running search-and-replace on the database without a dry run or a backup.
  • Forgetting links in widgets, footers and email templates, which the post editor search does not reach.

Questions people ask

Fix them at both ends. First decide what the dead target should do: restore it, redirect it with a 301 to the closest equivalent, or let it answer 404 or 410 if it is truly gone. Then edit every page that links to it so the link points straight at the live URL, including menus, footers and widgets. Search your CMS or source files for the old path to find every copy.

Run a broken link checker on your home page to catch menu and footer links, then on one page per template and on your most visited pages. Add Search Console's "Not found (404)" list, where URL Inspection shows the referring page, and check your sitemap URLs in bulk. Server logs with a referrer on your own domain point at the exact page with the broken link.

They do not trigger a penalty, but they cost you. Visitors hit a dead end, crawlers spend requests on URLs you do not want, and the page that should have received the link loses an internal signal of its importance. On a small site a few broken links matter little; in a menu or template they repeat on every page and are worth fixing first.

Usually because they are relative links without a leading slash. A link written as href="contact" resolves against the folder of the current page, so it works on the home page but points to /blog/post/contact on a blog post at /blog/post/. Write internal links as /contact/ or as full URLs, and the target stays the same on every page.

Check your site before and after Check