4xx broken link high
Broken Internal Link (4xx Page)
An internal link points to a URL on your own site that returns 404, 410, or 403, dead-ending visitors and crawlers.
What you see
404 Not Found The requested URL /blog/old-post was not found on this server. (Crawl report) Broken internal links: 1 link → https://example.com/blog/old-post returns 404
What’s actually happening
A visitor clicks a link in your nav, footer, or body copy and lands on your 404 page. In a crawl report (Screaming Frog, Ahrefs, Semrush) the destination URL shows a 4xx status code and the report lists the source pages linking to it. Googlebot follows the same link, hits the dead URL, and burns crawl budget on a page that returns nothing useful.
Common causes
- A page was renamed or its slug changed (e.g. /services/seo → /seo) but old internal links were never updated
- A page was deleted entirely and the links pointing to it were left behind
- Typo in the href — a missing trailing slash, wrong case (/About vs /about on a case-sensitive server), or a stray space
- A hard-coded absolute URL in a template, sidebar widget, or old blog post that still points at a defunct path
- A trailing-punctuation bug where the CMS appends a period or paren to the URL inside auto-linked text
How to fix it
- Find every source page linking to the dead URLRun a crawl in Screaming Frog, click the 404 URL, and open the 'Inlinks' tab to get the exact list of pages and the anchor text. Ahrefs Site Audit and Semrush both have an 'Internal links → Broken' filter that exports source+target pairs.
- Decide: fix the link or restore the targetIf the target page still exists at a new URL, update the href to the new path. If the page is genuinely gone but had value or backlinks, recreate it or 301 the old URL to the closest live equivalent so the links resolve.
- Edit the href at the source, not with a band-aid redirectFor links inside templates/widgets, fix the template once. For links in post bodies, edit each post (or run a SQL find-replace on wp_posts.post_content for WordPress: UPDATE wp_posts SET post_content = REPLACE(post_content,'/old-url','/new-url')). Prefer relative or root-relative URLs so domain/protocol changes don't break them again.
- Re-crawl to confirm zero 4xx internal linksAfter edits, re-run the crawl filtered to internal links with 4xx status. The count should be zero. Spot-check a few links in a real browser, not just the crawler.
Stop it recurring
Run a scheduled monthly crawl (Screaming Frog scheduling or a Semrush recurring audit) and never delete or rename a URL without searching the codebase/DB for inbound links first.
Related errors