There is no single tool that finds all orphan pages, because “orphaned” is a relational definition, a page is orphaned specifically when it exists in the site’s addressable URL space but has no internal link pointing to it from a page a standard crawler would otherwise reach. A link-following crawler, by design, can only find pages it can navigate to, so by definition it cannot independently discover the pages that are missing from that navigation graph. Detecting orphan pages reliably requires reconciling several separate URL universes, a crawl of the site’s link graph, the XML sitemap, server log data, Google Search Console’s Index Coverage/Pages report, and backlink data, and treating any URL that shows up in one of the latter sources but never in the crawl as an orphan candidate.
Why this has to be a reconciliation problem, not a single-tool problem
Each data source represents a different way a URL can be “known” without being internally linked. A link-following crawl (Screaming Frog, Sitebulb, or similar) represents the set of URLs reachable by starting at the homepage (or another seed) and following <a href> links, which is functionally the same discovery mechanism Googlebot uses when it isn’t relying on a sitemap or external links. The XML sitemap represents whatever URLs a CMS or generation script has declared to exist, which is frequently out of sync with the actual link graph, especially on large or old sites where sitemap generation logic and navigation/templating logic evolved independently over time. Server logs represent URLs that have actually been requested, by Googlebot, by other bots, or by users, which can surface pages that are still being crawled or visited via old external links or bookmarks even though no current internal path leads to them. Search Console’s Index Coverage (or the newer Page indexing report) represents Google’s own record of URLs it has crawled and/or indexed, which can include pages Google found through means outside your own crawl, like an external backlink or a stale sitemap entry from months ago. Backlink data (from Search Console’s Links report or a third-party index) represents URLs other sites are linking to, which is a completely independent discovery path from your own site’s internal structure and can turn up old campaign pages, deprecated product URLs, or pages that were unlinked internally after a redesign but never lost their external links.
None of these sources alone can prove a page is orphaned. A URL only in the sitemap might just be a sitemap error (a URL that never existed or was already removed). A URL only in the logs might be residual crawl activity for a page that was deliberately deprecated. The methodology that’s actually reliable is a set-difference operation: take the crawl-reachable set as the baseline of “pages with an internal path,” and treat any URL appearing in the sitemap, logs, GSC, or backlink data but absent from that baseline as a candidate orphan requiring manual or scripted verification of the specific reason it lacks an internal path.
The reconciliation workflow in practice
Start by producing a clean crawl of the site using a link-following crawler configured to ignore the sitemap as a seed (most tools by default will happily crawl from the sitemap as a shortcut, which defeats the purpose here; the crawl needs to represent only what’s reachable through actual on-page links from a normal starting point). This crawl is your baseline “linked URL” set.
Separately export the full XML sitemap URL list. Compare it against the baseline crawl set. URLs present in the sitemap but absent from the crawl are your first orphan candidate batch, these are pages the site claims exist and wants indexed but that have no internal path leading to them.
Pull server log data covering a meaningful window (ideally 30 to 90 days depending on traffic volume, to smooth out crawl frequency variance) and filter to requests from Googlebot’s declared user agent (verified via reverse DNS, since user-agent strings alone can be spoofed). Extract the distinct URL list Googlebot has actually requested. Compare this against the baseline crawl set. URLs Googlebot is actively requesting that don’t appear in your link-following crawl are a second orphan candidate batch, and this batch is particularly important because it tells you Google is still spending crawl resources on pages your own site no longer links to, which is both an orphan detection signal and a crawl budget hygiene issue.
Pull the Index Coverage or Page indexing report from Search Console, exporting the full list of indexed and known URLs. Compare against the baseline crawl set the same way. This surfaces pages Google has indexed that your current site structure doesn’t link to at all, which sometimes includes pages indexed long ago via a link structure that has since changed, or pages Google found via an external link and indexed independently of your internal architecture.
Pull backlink data from Search Console’s Links report (and, where available, a third-party backlink index for broader external coverage, since Search Console only reports links Google itself has recorded) and extract the distinct set of target URLs on your domain receiving external links. Compare against the baseline crawl set. Any URL receiving external links but absent from the internal crawl is a genuinely important orphan case, because it represents external authority (link equity) that your internal architecture is currently failing to connect to the rest of the site, and by extension failing to pass that equity anywhere useful.
After reconciliation: verifying and resolving true orphans
Once you have a merged candidate list (the union of sitemap-only, log-only, GSC-only, and backlink-only URLs relative to the crawl baseline), the next step is manual or scripted classification, because not every candidate is a genuine orphan requiring action. Some will be legitimately deprecated pages that should 404 or stay redirected and simply haven’t been purged from an old sitemap or backlink index. Some will be pages that exist and are valuable but were dropped from navigation during a template change or redesign, these are the priority fixes since they represent real content or link equity currently stranded. Some will be near-duplicate or parameter-variant URLs that were never meant to be independently linkable and are better handled with canonicalization or removal than with new internal links.
For each confirmed true orphan with real value (unique content, meaningful backlinks, or organic traffic history visible in Search Console performance data), the fix is to add a genuine internal link from a relevant, crawlable page, not just to add the URL to the sitemap, since sitemap presence alone doesn’t resolve the structural absence of an internal path and Google has been clear that sitemaps are a hint, not a substitute for actual site architecture. For confirmed candidates with no remaining value, the appropriate action is either a 301 redirect to a relevant surviving page (if there’s link equity worth preserving) or allowing/enforcing a 404 and removing the stale references from the sitemap and any other systems still declaring the URL as live.
This reconciliation process is exactly what log-file-analysis-oriented tools in the enterprise SEO space (systems built around this kind of crawl-versus-log-versus-index comparison) are built to operationalize at scale, but the methodology itself doesn’t require proprietary tooling, it requires deliberately pulling and diffing these independent URL universes rather than expecting any single crawl or report to surface the answer on its own.
A hypothetical illustration
Hypothetically, suppose a regional news publisher, call it Larkspur Daily, runs this reconciliation process across its archive and finds a batch of roughly 200 event-coverage articles from three years earlier that show up in Google Search Console’s Page Indexing report and in a third-party backlink index, several with real external links from other local news sites, but that never appear in a fresh link-following crawl starting from the current homepage. Digging in, hypothetically, the team discovers these articles were part of an old “Local Events” section that got removed from the main navigation during a site redesign, with no redirect and no replacement internal link path, even though the pages themselves were never deleted and are still live. Because those pages carry genuine external link equity, hypothetically the fix would be adding real contextual internal links back to them from a current, relevant section, an updated events archive page, say, rather than just re-adding the URLs to the sitemap, since sitemap presence alone wouldn’t resolve the actual structural gap that caused them to become orphaned in the first place.