How to Audit Hreflang at Scale
A repeatable, tool-driven process for auditing hreflang across a large site — pulling every annotation from all three implementation methods, reading cluster graphs and reciprocal matrices, and prioritizing fixes by damage, not frequency.
1 evidence signal on this page
- Related live toolreturntag - hreflang checker
Auditing hreflang at scale is a graph-validation problem, not a tag-validation problem: you check whether every page in a cluster points back to every other page, not whether one page has a tag. Pull every annotation from all three implementation locations (HTML head, HTTP headers, XML sitemap) with a crawler — Google gives you no validator and GSC's International Targeting report was removed Sept 22, 2022 — then build the reciprocal-tag matrix. Spot-check a cluster visually with my free returntag - hreflang checker graph and matrix, or use Ahrefs Site Audit and Screaming Frog for full-site coverage. Triage by damage: missing return tags first (they break the whole pair), then wrong language/region codes and non-canonical targets, then missing x-default last (most common at 56.3%, least harmful). In my Brighton SEO 2023 study of 374,756 domains, over 67% using hreflang had at least one error.
TL;DR — Auditing hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. “at scale” means checking your whole site’s hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. as one connected network instead of looking at pages one at a time. The trick is that hreflang works in matched pairs — if page A points to page B, B has to point back to A, or Google throws the whole pair out. A single-page check can never catch a missing return link, so you need a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. that reads every page and maps who points to whom. Fix the missing return links first; the missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" that every tool complains about can wait.
Why “one page at a time” doesn’t work
If you view-source on your German page and see a tidy block of hreflang tags, it looks fine. But hreflang only works if the pages it references point back. Your German page can be perfect and still be broken, because the English page it names forgot to name it in return. You can’t see that from the German page alone — you’d have to open the English page too, and the French page, and every other version, and cross-check them all by hand. On a ten-page site, fine. On a ten-thousand-page site, impossible.
That’s the whole reason “auditing hreflang at scale” is its own skill: you stop checking tags and start checking relationships. A tool crawls every page, records every hreflang annotation, and then asks the only question that matters — does every page in this group point to every other page, both directions?
Evidence for this claim A hreflang audit must verify return links because Google says non-reciprocal annotations may be ignored or interpreted incorrectly. Scope: Google Search hreflang reciprocity guidance; impact is stated as possible, not guaranteed cluster-wide invalidation. Confidence: high · Verified: Google: Hreflang guidelinesWhat you actually need
Three things:
- A crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index.. Google gives you no hreflang validator, and the old Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. report that used to flag some of this was removed back in 2022. So you lean on third-party crawlers — Ahrefs Site Audit or Screaming Frog — to pull everything into one place. Evidence for this claim A complete audit needs to inspect HTML, HTTP Link headers, and XML sitemaps because Google supports hreflang in all three locations. Scope: Google Search-supported hreflang delivery methods. Confidence: high · Verified: Google: Localized versions
- The reciprocal check. Both tools do the same core thing: they build a map of who-points-to-whom and flag the one-way links. Those one-way links are your “missing return tags,” and they’re the errors that actually matter.
- A priority order. You will find hundreds of issues. Fix the missing return links first (they break pairs), then wrong country/language codes, and leave the missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" for last — it’s the most common complaint but the least harmful.
The one thing to remember
Most sites that use hreflang have errors. When I studied 374,756 domains for Brighton SEO in 2023, over 67% of the ones using hreflang had at least one error. So don’t panic when your first crawl lights up red — that’s normal. The skill isn’t getting to zero errors; it’s knowing which of them actually cost you traffic and fixing those first.
For the broader international audit — URL structureURL structure is how the parts of a web address — scheme, domain, path, query string, and fragment — are organized and formatted. It mostly affects crawling, usability, and how engines understand a page, not rankings directly., geo-redirectsA geo-redirect automatically sends a visitor to a location- or language-specific URL based on IP or browser signals — a UX/serving mechanism that's separate from, and can actively undermine, hreflang., content quality, country performance — see International SEO Audit. For what hreflang even is and how to implement it, start with HreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others.. Want the full at-scale methodology — the reciprocal-tag matrix, the cluster-graph walkthrough, the Screaming Frog filters? Switch to the Advanced tab.
Validate hreflang fixes
Reciprocal cluster retest
Test to run: Re-crawl every changed cluster and compare actual self and alternate edges with the expected locale matrix. Expected result: Every member references itself and all intended alternates, and every edge has a return edge. Failure interpretation: The fix changed one template or page without updating the whole cluster. Monitoring window: Immediately after deployment and after the next generation cycle. Rollback trigger: A changed cluster still contains asymmetric priority-locale pairs.
Target integrity
Test to run: Request every changed hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. destination without following redirectsA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. and collect status, robots directives, and canonical. Expected result: Targets return direct 200 responses, remain indexable, and canonicalize as intended. Failure interpretation: The locale map points to obsolete, redirected, blocked, or consolidated URLs. Monitoring window: Release verification and the next full crawl. Rollback trigger: Any high-value cluster targets errors or unexpected non-canonical URLsHow search engines pick one canonical URL among duplicates and consolidate signals onto it..
Delivery-method consistency
Test to run: Compare annotations foundA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore. in HTML, HTTP headers, and XML sitemapsAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. for changed URLs. Expected result: Only the intended method is present, or all generated methods declare the same cluster. Failure interpretation: Multiple systems own hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. and have drifted. Monitoring window: After deployment and after the next sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. refresh. Rollback trigger: Contradictory methods remain on production URLs.
Code and scope validation
Test to run: Validate every changed value against supported language and region codes and the approved locale inventory. Expected result: Each value begins with a valid language and adds only an intentional valid region. Failure interpretation: A country was used as a language, an unsupported market leaked in, or casing/format generation is wrong. Monitoring window: In CI or predeployment QA and again in the production crawl. Rollback trigger: Invalid codes affect a generated template or multiple clusters.
TL;DR — A scaled hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. audit is graph validation, not tag validation. Step 1: pull every annotation from all three legal locations (HTML head, HTTP
Linkheaders, XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags.) with a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. configured for your ccTLDCountry-code top-level domain like .de or .co.uk — a strong geotargeting signal./subdomain setup — GSCA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. can’t do this (International Targeting removed Sept 22, 2022, and even before that it only reported the canonical member of a cluster). Step 2: build the reciprocal-tag matrix — every URL in a cluster × every other, does A→B exist, does B→A. Read it in my returntag - hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. checker cluster graph/matrix for a focused check, or use Ahrefs and Screaming Frog for site-wide crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor.. Step 3: classify into four patterns — missing return tags, wrong codes, non-canonical targets, mixed absolute/relative URLs. Step 4: prioritize by damage, not frequency — return tags first (they break the whole pair), then codes, then x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" last (most common at 56.3%, least harmful). Step 5: re-verify against the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. URL, not the declared canonical.
This article is the hreflang-specific companion to my broader International SEO Audit, which treats hreflang as one of six audit areas. Here I’m going one level deeper on the hreflang-only methodology at scale. For fundamentals — what hreflang is, the three ways to implement it, the reciprocal rule — see the HreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. hub and, for the fallback tag, x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\".
Evidence for this claim A complete audit needs to inspect HTML, HTTP Link headers, and XML sitemaps because Google supports hreflang in all three locations. Scope: Google Search-supported hreflang delivery methods. Confidence: high · Verified: Google: Localized versionsThe core reframe: this is a graph problem
Here’s the mental shift that makes scaled auditing tractable. You are not checking “does this page have a hreflang tag.” You’re checking “does every page in this page’s cluster point back to it, and does every URL in the cluster resolve to a 200, canonical, indexable page.”
Google’s own documentation is the reason:
Evidence for this claim A hreflang audit must verify return links because Google says non-reciprocal annotations may be ignored or interpreted incorrectly. Scope: Google Search hreflang reciprocity guidance; impact is stated as possible, not guaranteed cluster-wide invalidation. Confidence: high · Verified: Google: Hreflang guidelines“If page X links to page Y, page Y must link back to page X. If this is not the case for all pages that use
hreflangannotations, those annotations may be ignored or not interpreted correctly.”
Read that carefully. One missing return link can cause the affected annotations to be ignored or interpreted incorrectly. That’s why a single-page view is structurally incapable of auditing hreflang: the failure lives in the relationship between pages, not on any one page. You need a crawl that records every cluster member and cross-references them.
Scope matters here too: the ignored annotations are the ones in the broken pair, not automatically every relationship in a larger cluster. A five-page cluster with one missing return typically keeps processing its other complete pairs normally — that’s exactly what my returntag - hreflang checker screenshot below shows: nine reciprocal pairs intact, one missing return flagged. Don’t assume one broken edge nukes the whole cluster; go check every pair, because the tool has to check every pair to tell you that.
And it gets harder as the site grows — which is exactly Google’s own explanation for why big sites are the ones with errors. On Search Off the Record, Gary Illyes described the errors as emerging when a site has many properties, each with its own URL structureURL structure is how the parts of a web address — scheme, domain, path, query string, and fragment — are organized and formatted. It mostly affects crawling, usability, and how engines understand a page, not rankings directly. — as soon as you have to vary the pattern across properties, that’s where the errors come in, with Lizzi Sassman adding that it’s harder to sync them up when you’re localizing URLs and then making typos. That’s the signature of an enterprise setup: multiple ccTLDs, each on a slightly different publishing convention. So a good audit segments findings by property/domain group, because that’s where the errors actually cluster operationally.
Step 1 — Pull every hreflang annotation site-wide
The three places hreflang lives
Google accepts hreflang in three equivalent locations, and you must check all three:
- HTML
<link>tags in the<head>— the common case. - HTTP
Link:response headers — used for non-HTML files like PDFs. xhtml:linkentries in an XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. — common at scale because it centralizes the annotations in one file instead of templating them onto every page.
A crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. that only reads the HTML head will silently miss header- or sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.-declared alternates. It won’t flag them as broken — it just won’t see them, which is worse, because you’ll think a page has no hreflang when it actually has a full set delivered via sitemap. Configure the crawl to read all three before you trust a single number.
Configuring the crawler for your structure
- Screaming Frog: enable Configuration > Spider > Crawl Hreflang (this also picks up sitemap and header hreflang when you point it at them). For ccTLDs/subdomains that reference each other, add the sibling domains under Config > CDNs — otherwise cross-domain hreflang links are simply not validated, not flagged as broken. This is the single most common blind spot at scale, because enterprise sites are the ones most likely to use ccTLDs, and ccTLDs are exactly what needs this extra step.
- Ahrefs Site Audit: make sure the sibling domains are inside the project scope for the same reason. Then use Page Explorer to filter pages by hreflang issue type at scale before you drill into individual cluster graphs.
Why GSC can’t do this for you
Two reasons, and the second is the one most people miss:
- The report is gone. The GSC International Targeting report — which used to flag some hreflang issues — was deprecated and removed (announced August 2022; removed after September 22, 2022). Nothing replaced it directly.
- Even when it existed, it only ever showed the canonical. On Search Off the Record, Illyes explained that Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. only reports on canonicals — for most similar-language hreflang clusters, the alternates aren’t canonical, so you were effectively blind to what was happening on the non-canonical members of a cluster, because Google stores them in the duplicate cluster without keeping the alternate details. That’s a structural reason GSC was never a complete hreflang audit tool, not just “the report got removed.” It’s the direct justification for going crawler-first.
Google also just doesn’t ship a validator. On the same podcast, Illyes said Google has never provided an hreflang validator — they had some underused reporting and then removed it — and now points people to external tools like Aleyda Solis’ tool, Bill Hunt’s hreflang checker, and Merkle’s tool. Take that as permission to lean on third-party crawlers for the job GSC can’t do — but not as an endorsement. Google’s own documentation is explicit that it doesn’t maintain or check third-party hreflang debugging tools, so treat any tool’s output, mine included, as diagnostic evidence you still have to reason about, not an official verdict. When a finding actually matters, confirm it against the raw artifact — the HTTP response, the sitemap XML, or the rendered HTML — rather than stopping at the tool’s parsed summary.
Step 2 — Build the reciprocal-tag matrix
Normalize what you pulled
Before you build the matrix, get everything into one consistent shape. For every declared hreflang relationship, record the source URL, the target URL, the locale value, the source method (HTML head, HTTP header, or sitemap), and — critically — the target’s status code, redirect chainA → B → C instead of A → C. Each hop loses link equity and adds latency., indexability, canonical target, and whether the crawl saw it in raw HTML or the rendered DOM. Different crawlers export this differently; normalizing it into directed URL-to-URL edges with that context attached is what makes the matrix, and every classification in Step 3, reliable instead of a pile of disconnected rows.
What the matrix represents
Conceptually, for each cluster you build a table where the rows and columns are every URL in that cluster, and each cell answers a yes/no question: does a hreflang link exist from the row URL to the column URL? A correct cluster is symmetric — if A→B is present, B→A is present. Every asymmetric cell (a link that exists in one direction only) is a missing return tag.
You don’t literally hand-build this spreadsheet at scale — the tools build it for you. But holding the matrix in your head is what lets you read the tool output correctly. My returntag - hreflang checker tool draws the matrix as a graph and also exposes the underlying cells; Screaming Frog’s “Missing Return Links” filter pulls the asymmetric cells into a list, and Ahrefs Site Audit provides another at-scale cluster view. Same relationship check, different presentations and crawl scopes.
Reading it as a graph: my returntag - hreflang checker cluster validator
For a focused cluster check, my free returntag - hreflang checker tool renders the declared locale
relationships as a graph and a reciprocal matrix. Every locale is a node, every
declared hreflang annotation is an edge, and the issue list identifies the exact URL
that fails to link back. The screenshot below is a sitemap-only run: it reads what the
sitemap declares and deliberately does not fetch page head tags or HTTP Link headers.
Use Page URL mode when you need the full three-source picture for a page’s cluster.
How to read it:
- A clean cluster is a fully-connected mesh — every node linked to every other node, both directions.
- A one-way edge is your asymmetric cell: page X points to Y but Y doesn’t point back. That’s the return-tag error, seen instead of read.
- An orphaned node — a URL that appears in the cluster but doesn’t link back into it — is an unlinked hreflang URL.
The practical win is triage speed and stakeholder communication: instead of handing a developer an abstract spreadsheet row, you show the one-way relationship and the exact missing return-tag error together. For hundreds or thousands of clusters, keep Ahrefs Site Audit or Screaming Frog in the workflow for complete crawl coverage; returntag - hreflang checker is the fast way to inspect and explain a specific cluster.
Turn a hard-to-read hreflang cluster into a graph, matrix, and exact fix with my free returntag - hreflang checker Free
- Run Page URL mode for a page-level cluster or Sitemap mode for declared sitemap relationships.
- Switch between Graph and Matrix, then open the exact missing-return issue.
- Use Ahrefs Site Audit or Screaming Frog when you need exhaustive site-wide crawl coverage.
The returntag - hreflang checker sitemap-only result reads five URLs and 24 annotations across en-US, en-GB, fr-FR, de-DE, and x-default. It reports nine reciprocal pairs, one missing return, and zero broken targets. The graph shows the otherwise connected five-node cluster and highlights the one-way relationship from en-US to fr-FR. The issue states that https://example.com/fr-fr/ does not link back to https://example.com/en-us/, so the return tag is missing. The tool notes that sitemap-only mode does not fetch page head tags or HTTP Link headers.
Reading it as a spreadsheet: the Screaming Frog filters
If you’re in Screaming Frog, the matrix surfaces as a set of filters (after you run Crawl Analysis post-crawl to populate the return-link data). Work them in roughly this order, because it maps to the priority order in Step 4:
- Missing Return Links — the asymmetric cells; your highest-priority findings.
- Inconsistent Language & Region Return Links — a return link exists but with a
different code than the outbound one (A says B is
fr-FR, B says A isen-GBwhen A is reallyen-US) — a subtler pair-breaker. - Non-Canonical Return Links — the return link points at a URL that’s canonicalized elsewhere, so the signal chain breaks even though a tag exists.
- NoindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. Return Links — the return target is noindexed, so it can’t carry the annotation.
- Non-200 Hreflang URLs — the target is a redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. or an error page.
- Unlinked Hreflang URLs and Incorrect Language & Region Codes — orphaned nodes and code-validation errors.
Export the whole set via Reports > Hreflang. (For the full filter-by-filter walkthrough at the summary level, the Screaming Frog hreflang tutorial is excellent — I’m not going to re-type their config steps here.)
Step 3 — Classify what you find into four error patterns
Your crawl output will be noisy. Sort every finding into one of four buckets — these are the patterns that repeat across the 374,756-domain study. (I’m pulling only the two figures that anchor the priority argument; the full nine-type error table is already in the International SEO Audit article — no point re-pasting it.)
1. Missing return tags — the pair-breaker
The asymmetric cells from your matrix. 15.3% of hreflang-using domains have these. As I put it in the study writeup: “As I mentioned, hreflang tags work in pairs. If both pages don’t reference each other, they can’t establish the connection and swap properly in the search results.” This is the category that invalidates the whole pair’s signal per Google’s docs, which is why it’s first in the priority order — even though it’s not the most common error.
2. Wrong language/region codes — the quietly-forgiving one
Use ISO 639-1Two-letter language codes used in hreflang (en, es, de). for language and ISO 3166-1 alpha-2Two-letter country codes used in hreflang region targeting (us, gb, au). for region. The classic breakers:
jp instead of ja for Japanese, the typo js for ja, three-letter codes like
gbr instead of gb, la (Laos) misused for “Latin America.”
One more distinction worth building into your audit: BCP 47 (the underlying
language-tag spec) permits a much broader set of values than Google’s hreflang
implementation actually acts on — script subtags and other BCP 47-legal constructs
that Google’s own hreflang documentation doesn’t confirm as recognized values. A
code can be perfectly well-formed BCP 47 and still not be something Google’s
hreflang guidance documents as supported. Validate against Google’s documented
language/region/x-default rules specifically, not generic BCP 47 well-formedness
— a syntactically valid tag can still be functionally invisible to Google.
But here’s the nuance that cuts against naive prioritization: Google silently corrects
some of these and not others. Its documentation states that if you use codes reserved
for something else, “Google Search ignores that part of the annotation (for example,
using EU, UN, or UK in hreflang annotations doesn’t have an effect on Google
Search).” So UK is effectively dropped (you want GB), but it doesn’t nuke the rest
of the annotation — whereas a code that’s simply wrong (jp for ja) does break that
pair. An audit needs to distinguish “technically wrong but Google handles it” from
“wrong and actually breaks the pair,” because they don’t get the same urgency.
3. Non-canonical URLs in hreflang — the invisible one
This is the pattern that looks fine in a tag export and breaks anyway. A key distinction I drew at Pubcon 2019: hreflang is about the indexed version, not the canonical. If your hreflang points to a URL that’s canonicalized away from what’s actually indexed, the signal chain breaks even though the tag itself is “valid.” This only surfaces when you cross-reference the crawl export against indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. status — most hreflang tutorials skip it because they treat hreflang as an isolated tag check instead of part of the indexing pipeline. (More on verifying this in Step 5.)
There’s a same-language alignment check worth adding here too. When several near-duplicate URLs could plausibly serve as the canonical for a locale, Google’s own canonicalizationHow search engines pick one canonical URL among duplicates and consolidate signals onto it. guidance favors a same-language (or best-substitute) URL, and gives some preference to a page that’s part of a complete reciprocal hreflangIf page A lists page B as an alternate, B must list A back — or Google ignores the pair. cluster over one that isn’t. That’s a reason to keep hreflang targets pointed at same-language canonical candidates rather than letting them drift onto a different-language duplicate. None of this is something a crawler or checker can prove outright, though — it can show you the configured signals (canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content., hreflang edges, cluster membership), not Google’s actual final selection. Treat crawl output as diagnostic evidence, not confirmation.
4. Mixed absolute/relative URLs — the templating bug
Google is explicit: “Alternate URLs must be fully-qualified, including the transport
method (http/httpsHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.'), so: https://example.com/foo, not //example.com/foo or
/foo.” At scale this is almost never a one-off typo — it’s a templating bug that hits
thousands of URLs at once because the hreflang block is generated from a partial URL
pattern. That’s why crawlers flag it as a systemic issue: find one, and you’ve usually
found a whole template’s worth.
Step 4 — Prioritize: return tags first, codes next, x-default last
The single most important idea in this whole article: error severity is not proportional to error frequency. Sort your findings by damage, not by how many rows the tool returned.
| Tier | Error pattern | Why here |
|---|---|---|
| 1 — fix first | Missing return tags; inconsistent return-link codes | Breaks the entire pair’s signal per Google’s docs. Highest damage. |
| 2 — fix next | Wrong codes that Google doesn’t silently fix (jp→ja); non-canonical / broken targets | Breaks individual relationships; some are silently handled, some aren’t — triage accordingly. |
| 3 — batch | Mixed absolute/relative URLs, missing self-reference | Real hygiene issues, usually template-wide, but not always cluster-breaking. |
| 4 — last | Missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" | Most common, least damaging. |
Why x-default goes last despite being everywhere: it’s the single most common finding in every study — 56.3% in my 374,756-domain study, and 47.95% in Dan Taylor’s independent 18,786-domain SALT.agency study (two studies, very different scales, same headline: most sites are missing it). But as I wrote in the study: “Setting an x-default is not required. But it is recommended if you need a fallback page for users whose language settings don’t match any of your localized versions.” Google’s own team treats it as a UX fallback, not an indexing-critical signal — on Search Off the Record, Illyes described x-default as annotating a fallback page for when there’s no matching language for a user, and noted it can even be another language page rather than a dedicated selector. Fix it, but fix it after the things that actually break clusters.
Self-reference sits in tier 3 for the same reason: even Illyes, who worked on Google’s hreflang implementation, said on record he doesn’t fully remember why self-reference is required and is fairly sure clusters would work without it — he framed it mainly as making clusters easier to set up because you can copy/paste the same block everywhere. It’s implementation hygiene, not a functional requirement.
For the broader impact × effort matrix that spans all six international audit areas (not just hreflang), use the Frameworks lens in International SEO Audit rather than rebuilding it here.
Step 5 — Re-verify against the indexed URL, not the crawl
Your crawl validates the tags. It doesn’t validate that the URL the tag points to is the one Google actually indexed. Because hreflang follows the indexed version (Step 3, pattern 3), a tag that points at a URL that’s been canonicalized away — or that redirects, or is noindexed downstream — still breaks the signal even after your bulk fix pass reports “clean.”
So after the fixes ship, spot-check the highest-value clusters with URL Inspection in Search Console: confirm the URL Google reports as indexed is the same URL your hreflang references. This is the step that catches canonical-chain drift, which is invisible in a plain hreflang-tag export. You don’t do it for every URL — you do it for your money pages in each market, after the crawl says you’re done.
A one-line note on Bing
Don’t expect Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility. to validate any of this. Bing treats hreflang as a much weaker signal than Google does and removed its GeoGenerative Engine Optimization — visibility inside AI answer engines. Targeting feature back in 2020 — it leans on the Content-Language header instead. A hreflang-at-scale audit is fundamentally a Google-facing exercise; check Content-Language for Bing separately (covered in International SEO Audit).
AI summary
A condensed take on the Advanced version:
- It’s a graph problem, not a tag problem. You check whether every page in a cluster points back to every other page — not whether one page has a tag. Per Google: “If page X links to page Y, page Y must link back to page X,” or the annotations “may be ignored.” One missing return link can invalidate a whole cluster.
- Step 1 — pull everything. HreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. lives in three places (HTML head, HTTP
Linkheaders, XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags.); a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. must read all three. Configure ccTLDCountry-code top-level domain like .de or .co.uk — a strong geotargeting signal./subdomain siblings (Screaming Frog: Config > CDNs; Ahrefs: project scope) or cross-domain links go unvalidated. GSCA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. can’t do this — the International Targeting report was removed Sept 22, 2022, and even before that it only reported the canonical member of a cluster. - Step 2 — the reciprocal-tag matrix. Every URL × every URL in a cluster; asymmetric cells = missing return tags. Read a focused cluster visually in the returntag - hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. checker graph and matrix**, or work site-wide through Ahrefs Site Audit and Screaming Frog.
- Step 3 — four error patterns: missing return tags; wrong codes (Google silently fixes
reserved ones like
UK→ignored, not others likejpforja); non-canonical targets (hreflang follows the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. URL); mixed absolute/relative URLs (a template bug at scale). - Step 4 — prioritize by damage, not frequency. Return tags first (break the whole pair), then codes/broken targets, then x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" last — most common (56.3% in my 374,756-domain study; 47.95% in SALT.agency’s) but least harmful and “not required.”
- Step 5 — re-verify against the indexed URL with URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. after the fix pass; the crawl validates tags, not indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.-status drift.
- Scale context: over 67% of hreflang-using domains have at least one error (my Brighton SEO 2023 study of 374,756 domains). Bing is a one-line caveat — check Content-Language, not hreflang.
Official documentation
Primary-source references for a hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. audit.
- Tell Google about localized versions of your page — the hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. reference: the reciprocal return-tag requirement, the fully-qualified-URL rule, reserved-code handling, and the three equivalent implementation methods (HTML link tags, HTTP
Linkheaders, XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags.). - The International Targeting report is deprecated — Search Console Help — the removed report that used to flag some hreflang issues (removed after September 22, 2022).
- Managing Multi-Regional and Multilingual Sites — URL-structure context for why multi-property setups generate the most hreflang errors.
- How to specify a canonical URL with rel=canonical and other methods — the same-language canonical-preference guidance behind Step 3’s non-canonical hreflang check.
Bing / Microsoft
- Bing Webmaster Tools help — Bing has no hreflang validation workflow; it weights the Content-Language header instead and removed GeoGenerative Engine Optimization (GEO) is the practice of optimizing content and brand presence so AI-powered search engines and assistants — Google AI Overviews, ChatGPT, Perplexity — cite, recommend, or mention you when generating answers. Google's position is that it's still SEO. Targeting in 2020.
Quotes from the source
On-the-record statements that anchor the audit methodology.
Google — the reciprocal requirement (the backbone of the whole audit)
- “If page X links to page Y, page Y must link back to page X. If this is not the case for all pages that use
hreflangannotations, those annotations may be ignored or not interpreted correctly.” — Google Search Central docs. Jump to quote
Google — fully-qualified URLs (root cause of the mixed absolute/relative pattern)
- “Alternate URLs must be fully-qualified, including the transport method (http/httpsHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.'), so:
https://example.com/foo, not//example.com/fooor/foo.” — Google Search Central docs. Jump to quote
Google — reserved codes are silently dropped, not page-breaking
- “If you use codes that are listed as reserved for something else, Google Search ignores that part of the annotation (for example, using
EU,UN, orUKinhreflangannotations doesn’t have an effect on Google Search).” — Google Search Central docs. Jump to quote
Patrick Stox — why pairs are load-bearing (from the 374,756-domain study)
-
“As I mentioned, hreflang tagsHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. work in pairs. If both pages don’t reference each other, they can’t establish the connection and swap properly in the search results.” — Over 67% of Domains Using Hreflang Have Issues, Ahrefs
-
“Setting an x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" is not required. But it is recommended if you need a fallback page for users whose language settings don’t match any of your localized versions.” — Over 67% of Domains Using Hreflang Have Issues, Ahrefs
Gary Illyes, Google — why GSCA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. can’t audit hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others., and why there’s no validator
- On Search Off the Record, Illyes explained that Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. only reports canonicals, so for the many hreflang clusters where the alternates aren’t canonical you’re effectively blind to the non-canonical members — Google puts them in the duplicate cluster without storing the alternate details. He also said Google has never provided an hreflang validator (they had underused reporting and removed it) and now points people to external tools. Paraphrased from the transcript — verify wording against the episode page before quoting verbatim.
Which finding do I fix first?
You’ve run the crawl and you’re staring at a wall of red. Walk each finding through this:
-
Is the return link missing or code-inconsistent (asymmetric cell)? → Yes → Tier 1. Fix now. This breaks the whole pair per Google’s docs. Everything else waits behind this. → No → continue.
-
Does the hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. point to a non-200, redirected, noindexed, or non-canonical URLHow search engines pick one canonical URL among duplicates and consolidate signals onto it.? → Yes → Tier 2. Fix next. The target can’t carry the annotation. For non-canonical specifically, confirm against the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. URL (URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version.), not just the canonical tag. → No → continue.
-
Is the language/region code wrong? → Is it a reserved code Google silently ignores (
UK,EU,UN)? → Yes → low urgency. Google drops just that part; fix for correctness, not as an emergency. → Is it a genuinely wrong code that breaks the match (jpforja,jstypo, three-lettergbr)? → Yes → Tier 2. Fix next. This breaks the relationship. -
Is it a mixed absolute/relative URL (
//example.com/…or/…)? → Yes → Tier 3, but check the template. Almost always a site-wide templating bug — one instance means thousands. Fix at the template, batch the rest. -
Is it a missing self-reference or missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\"? → Yes → Tier 4. Last. Real hygiene, not cluster-breaking. x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" is “recommended, not required”; self-reference is copy/paste convenience. Do these in a final sweep.
The rule underneath the tree: sort by damage, not by how many rows the tool returned. The most common error (x-default) is the least damaging.
SOP: the recurring hreflang audit
HreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. breaks silently every time developers ship a template change, so run this on a schedule (monthly for active international sites, or after any release that touches localized templates).
Prep
- Confirm crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. scope covers every property in the hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. network — all ccTLDsCountry-code top-level domain like .de or .co.uk — a strong geotargeting signal., subdomains, subfolders. In Screaming Frog, add siblings under Config > CDNs; in Ahrefs Site Audit, confirm they’re in project scope.
- Confirm the crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. reads all three annotation locations (HTML head, HTTP
Linkheaders, XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags.). Verify by checking a page you know uses sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.-based hreflang.
Crawl 3. Enable hreflang extraction (Screaming Frog: Configuration > Spider > Crawl Hreflang). Run the crawl. 4. Run post-crawl analysis (Screaming Frog: Crawl Analysis) so return-link filters populate. In Ahrefs, let Site Audit finish and open the hreflang issue set.
Triage (in this order) 5. Tier 1 — Missing Return Links + Inconsistent Return-Link Codes. Export these first. Open the worst-hit clusters in the returntag - hreflang checker graph/matrix to explain the broken edges; retain the crawler export as the site-wide source of coverage. 6. Tier 2 — Non-canonical / broken / noindexed targets, and genuinely wrong codes. 7. Tier 3 — Mixed absolute/relative URLs (fix at the template), missing self-reference. 8. Tier 4 — Missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\". Last.
Segment 9. Group every finding by property/domain, not just by error type — errors cluster where URL patterns vary across properties. This tells you which team’s template to fix.
Verify 10. After fixes ship, re-crawl. Then spot-check money pages per market with URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. to confirm hreflang points to the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. URL, not a canonicalized-away one. 11. Record the error counts by tier each cycle so you can see drift over time.
Hreflang audit myths and mistakes
Concrete misconceptions that lead people to audit the wrong things — each with why it’s wrong and what to do instead.
1. “Broken hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. gets my site penalized, so any error is urgent.”
- Why wrong: Google ignores broken or asymmetric hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others.; it doesn’t penalize for it. Gary Illyes has said directly that an incorrect hreflang implementation won’t hurt a site — Google simply ignores it (reported by Search Engine Roundtable and corroborated by Search Engine Journal). The cost is lost opportunity (wrong-language pages surfacing, market cannibalization), not a ranking penalty.
- Do instead: Triage by lost opportunity per cluster (traffic, revenue), not by fear of a penalty that doesn’t exist.
2. “Missing x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" is the most common error, so fix it first.”
- Why wrong: Frequency and severity are different axes. x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" is the single most common finding (56.3% in my study; 47.95% in SALT.agency’s) but it’s “recommended, not required” and functions as a UX fallback, not a cluster-critical signal.
- Do instead: Put x-default last. Fix missing return tags first — they break entire pairs.
3. “Self-referencing tags are mandatory, flag every missing one as critical.”
- Why wrong: Even Illyes, who worked on Google’s hreflang implementation, said on record he isn’t sure why self-reference is required and believes clusters would work without it — it’s mainly copy/paste convenience.
- Do instead: Fix self-reference in the final hygiene sweep (tier 3–4), not ahead of return-tag and code errors.
4. “The html lang attribute is a language signal Google checks, so audit it alongside
hreflang.”
- Why wrong: Asked directly on Search Off the Record whether Google cares about the HTML
langattribute, Illyes said no — it’s often baked into CMSA content management system (CMS) is software that lets users create, manage, and publish digital content — like blog posts and pages — without writing raw code. WordPress, Drupal, and Joomla are the most common open-source CMS platforms. templates by default and therefore untrustworthy, so Google detects language from the visible content instead. - Do instead: Keep
html langcorrect for accessibilityWeb accessibility means designing sites so people with disabilities can use them, per the W3C's WCAG guidelines. It overlaps with SEO in specific, checkable ways — alt text, heading structure, descriptive link text, captions, and page speed all serve both audiences — but Google has said accessibility itself is not a ranking factor, and most WCAG success criteria (keyboard focus order, ARIA live regions, form labels) have no SEO effect at all. and other engines, but don’t let a hreflang-vs-langmismatch outrank an actual return-tag error in your triage.
5. “GSCA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.’s report is gone, so without a paid crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. I can’t audit hreflang at all.”
- Why wrong: A manual view-source spot-check plus free/freemium validators (Aleyda Solis’ tool, Bill Hunt’s checker, Merkle’s tool — all named by Illyes as tools he’s foundA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore. reliable, though Google’s own documentation is clear it doesn’t maintain or check third-party hreflang tools) work fine for small sites. It’s scale that requires a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index., not the absence of GSC.
- Do instead: Match the tool to the size. Spot-check small sites manually; reserve the crawler for the sites where hand-checking clusters is genuinely impossible.
6. “My hreflang export is clean, so hreflang is fine.”
- Why wrong: A clean tag export doesn’t mean the targets are indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.. Hreflang follows the indexed URL, not the canonical — a tag pointing at a canonicalized-away or noindexed URL still breaks even though the tag “looks” valid.
- Do instead: Cross-reference against indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. status (URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version.) for your top clusters after the tag-level pass.
Before / after: reading the four patterns
Concrete, minimal examples of each error pattern and its fix. (Illustrative markup.)
1. Missing return tag (the pair-breaker)
Before — the US page points to the UK page, but the UK page never points back:
<!-- https://example.com/us/ (present) -->
<link rel="alternate" hreflang="en-US" href="https://example.com/us/" />
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />
<!-- https://example.com/uk/ (BROKEN — no link back to /us/) -->
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />After — the UK page names the US page in return, so the pair is symmetric:
<!-- https://example.com/uk/ (fixed) -->
<link rel="alternate" hreflang="en-US" href="https://example.com/us/" />
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />2. Wrong language/region code
Before — jp is a country code, not the language code for Japanese; en-UK isn’t valid:
<link rel="alternate" hreflang="jp" href="https://example.com/jp/" />
<link rel="alternate" hreflang="en-UK" href="https://example.com/uk/" />After — ISO 639-1Two-letter language codes used in hreflang (en, es, de). language (ja) and ISO 3166-1 alpha-2Two-letter country codes used in hreflang region targeting (us, gb, au). region (GB, not UK):
<link rel="alternate" hreflang="ja" href="https://example.com/jp/" />
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />3. Mixed absolute/relative URLs (a template bug at scale)
Before — protocol-relative and root-relative URLs; Google requires fully-qualified:
<link rel="alternate" hreflang="fr-FR" href="//example.com/fr/" />
<link rel="alternate" hreflang="de-DE" href="/de/" />After — fully-qualified, including the transport method:
<link rel="alternate" hreflang="fr-FR" href="https://example.com/fr/" />
<link rel="alternate" hreflang="de-DE" href="https://example.com/de/" />4. Non-canonical target (looks valid, still breaks)
Before — the hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. points at a URL that’s canonicalized away from the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. version:
<!-- hreflang points here… -->
<link rel="alternate" hreflang="es-ES" href="https://example.com/es/producto?ref=nav" />
<!-- …but /es/producto?ref=nav has: <link rel="canonical" href="https://example.com/es/producto"> -->After — hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. points at the canonical/indexed URL, so the signal chain holds:
<link rel="alternate" hreflang="es-ES" href="https://example.com/es/producto" />The catch with #4: you can’t see it from the tag alone. Confirm the indexed URL with URL Inspection before you trust that this one’s fixed.
Pulling and checking hreflang yourself
For spot-checks, ad-hoc extraction, and validating a fix before the next full crawl. The crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. is still your source of truth at scale — these are for the in-between.
Chrome DevTools Console — dump every hreflang on the current page
Paste into the Console on any page to list its annotations and flag protocol-relative or root-relative URLs:
[...document.querySelectorAll('link[rel="alternate"][hreflang]')]
.map(l => {
const href = l.getAttribute('href');
const bad = /^\/\//.test(href) || /^\/(?!\/)/.test(href);
return `${l.hreflang}\t${href}${bad ? '\t⚠ not fully-qualified' : ''}`;
})
.join('\n') || 'No HTML hreflang tags on this page (check headers / sitemap).';If it prints “No HTML hreflang tagsHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others.,” the page may deliver hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. via HTTP header or sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. — the Console only sees the DOM, so check those separately.
Bookmarklet — one-click reciprocity spot-check across a cluster
Fetches every alternate the current page names and reports which ones fail to link back (same-origin only, due to browser CORS — cross-ccTLDCountry-code top-level domain like .de or .co.uk — a strong geotargeting signal. pairs need the crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index.):
javascript:(async()=>{const base=location.href.split('#')[0];const alts=[...document.querySelectorAll('link[rel="alternate"][hreflang]')].map(l=>({lang:l.hreflang,href:l.href})).filter(a=>a.lang!=='x-default');const out=[];for(const a of alts){try{const html=await(await fetch(a.href)).text();const back=/hreflang=["'][^"']*["']\s+href=["']([^"']+)["']/gi;let m,found=false;while((m=back.exec(html))){if(m[1].split('#')[0].replace(/\/$/,'')===base.replace(/\/$/,'')){found=true;break;}}out.push(`${found?'✓':'✗ MISSING RETURN'} ${a.lang} ${a.href}`);}catch(e){out.push(`? ${a.lang} ${a.href} (fetch blocked — cross-origin)`);}}alert(out.join('\n'));})();grep / regex — extract hreflang from a saved sitemap or HTML dump
Pull every annotation out of a downloaded XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. or crawl HTML export:
# From an XML sitemap using xhtml:link hreflang
grep -oE 'hreflang="[^"]+"[^>]*href="[^"]+"' sitemap.xml
# From a directory of saved HTML pages — list hreflang value + href per file
grep -rhoE '<link[^>]*hreflang="[^"]+"[^>]*>' ./pages/ \
| grep -oE 'hreflang="[^"]+"|href="[^"]+"'Python — build the reciprocity matrix from a Screaming Frog export
Turn a Screaming Frog hreflang_all.csv-style export (columns: source URL, hreflang value,
target URL) into a set of one-way (missing-return) pairs:
import csv
from collections import defaultdict
links = defaultdict(set) # source -> set of targets it points to
with open("hreflang_export.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
src, tgt = row["Address"].strip(), row["Occurrence URL"].strip()
if src and tgt and src != tgt:
links[src].add(tgt)
missing = [(a, b) for a, targets in links.items()
for b in targets
if a not in links.get(b, set())]
print(f"{len(missing)} one-way (missing-return) pairs:")
for a, b in missing[:50]:
print(f" {a} -> {b} (no return link)")Adjust the column names to match your export. The output is exactly the asymmetric cells of the reciprocal-tag matrix — the tier-1 fixes.
Patrick's relevant free tools
- Google Search Console Hidden Query Estimator — Upload a Search Console performance export plus an Ahrefs or Semrush keyword export, and see which queries plausibly explain the clicks and impressions GSC hides below its privacy threshold — per-page confidence-tiered estimates, CSV export. Runs entirely in your browser.
- hreflang Generator + Linter — Enter your URL × locale matrix and get bidirectional hreflang markup as head tags, sitemap XML (auto-split past 50,000 URLs), and Link headers — linted live for wrong region codes, duplicates, and missing fallbacks. Runs entirely in your browser.
Tools for a scaled hreflang audit
- returntag - hreflang checker (primary for graph/matrix spot-checks). My free tool turns a page or sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. cluster into a graph and reciprocal matrix, then names missing return relationships and their fixes. Page URL mode checks a page cluster; SitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. mode validates only what the sitemap declares. Use it to investigate and communicate a specific cluster, not as a substitute for a whole-site crawl.
- Ahrefs Site Audit (at scale). Extracts hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. from HTML, headers, and sitemaps, runs the reciprocal checks, and renders each cluster as a network graph — URL Details > HreflangsHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. tab, broken edges in red. The fastest way to see which relationship in a cluster is broken, and the easiest to show a stakeholder. Use Page Explorer to filter pages by hreflang issue type before drilling into individual graphs.
- Screaming Frog SEO SpiderA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index.. Enable Configuration > Spider > Crawl Hreflang; add sibling ccTLDsCountry-code top-level domain like .de or .co.uk — a strong geotargeting signal. under Config > CDNs for cross-domain validation; run Crawl Analysis to populate the return-link filters (Missing Return Links, Inconsistent Language & Region Return Links, Non-Canonical Return Links, NoindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. Return Links, Non-200 Hreflang URLs, Unlinked Hreflang URLs). Export via Reports > Hreflang. Their hreflang tutorial is the definitive config reference.
- Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. — URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version.. Not for bulk auditing (the International Targeting report is gone, and GSC only ever reported the canonical member of a cluster), but essential for Step 5: confirming your hreflang points at the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. URL after the fix pass.
- Free/freemium validators for small sites and spot-checks — Aleyda Solis’ hreflang tag generator/tester, Bill Hunt’s hreflang checker, and Merkle’s hreflang tool (named by Google’s Gary Illyes as tools he knows work well — though Google’s own documentation is explicit that it doesn’t maintain or check third-party hreflang tools). Use these when hand-checking is still feasible; reserve the crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. for true scale, and treat any tool’s verdict as diagnostic, not official.
- Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility. — no hreflang validation; audit Content-Language separately for Bing markets.
Resources worth your time
My related writing
- Over 67% of Domains Using Hreflang Have Issues (Study of 374,756 Domains) — my Brighton SEO 2023 study, the largest hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. study to date and the spine of this whole methodology; the error distribution and the return-tag/x-defaultx-default is the reserved hreflang value that points to a fallback URL — the page Google shows when a user's locale doesn't match any of your other hreflang tags. It is optional and does not mean \"English.\" figures come from here.
- Hreflang: The Easy Guide for Beginners — the Ahrefs implementation guide, for the fundamentals this article assumes you already know.
- The Beginner’s Guide to Technical SEO — where international signals sit in the wider technical picture.
My speaking
- Hreflang Study and Interesting Issues — Brighton SEO 2023 (Speaker Deck) — the slides behind the study.
- The most common hreflang issues across 374,756 domains — Brighton SEO, Sept 2023 (YouTube) — the talk itself.
- International SEO: The Weird Technical Parts — Pubcon Vegas 2019 (SlideShare) — where I make the “hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others. follows the indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. version, not the canonical” point that drives Step 3 and Step 5.
From around the industry
- Tell Google about localized versions of your page — Google’s canonical hreflang reference (reciprocity, fully-qualified URLs, reserved codes).
- Search Off the Record — “How serving works, hreflang, and more!” — Google’s Search Relations team (Illyes, Splitt, Sassman) on why GSCA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. only reports canonicals, why there’s no validator, and why big multi-property sites generate the most errors.
- How To Audit & Test Hreflang (Screaming Frog) — the definitive filter-by-filter config walkthrough.
- Study: 31% of international websites contain hreflang errors (Search Engine Land) — Dan Taylor / SALT.agency’s independent 18,786-domain study, a useful cross-check on my larger one.
- Google Says They Will Ignore Incorrect hreflang Implementation (Search Engine Roundtable) — the “ignored, not penalized” point that reorders your triage away from panic.
- Google Insights: Can Incorrect Hreflang Tags Hurt SEO? (Search Engine Journal) — corroborates the same finding.
Test yourself: Auditing hreflang at scale
Five quick questions on the at-scale methodology. Pick an answer for each, then check.
Reciprocal hreflang
If page A lists page B as an alternate, B must list A back — or Google ignores the pair.
Related: Hreflang
Reciprocal hreflang
The requirement that if page A lists page B as an alternate, page B must also list page A. Google ignores one-sided hreflangHreflang is an annotation (in HTML, HTTP headers, or XML sitemaps) that tells search engines which language and optional region a page targets, and which alternate versions exist. It only works when every page in the cluster references all the others..
Related: Hreflang
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 25, 2026.
Editorial summary and recorded change details.Summary
Aligned legacy tool display names with returntag - hreflang checker and Scout Site Audit Free.
Change details
-
Updated the linked tool names to match their current public labels.
Full comparison unavailable — no prior snapshot was archived for this revision.
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Tightened the audit methodology against Google's own documentation: scoped the reciprocity failure to the affected pair (not the whole cluster), distinguished Google's supported hreflang codes from generic BCP 47 validity, added a normalized extraction-schema step before matrix-building, connected non-canonical checks to Google's canonical-preference guidance, and added Google's explicit caveat that third-party hreflang tools aren't maintained or checked by Google.
Change details
-
Clarified that a missing return link affects only that pair's annotations, not automatically every relationship in the cluster.
-
Added a BCP 47-vs-Google's-supported-values distinction to the wrong-codes section.
-
Added a 'normalize what you pulled' step before matrix-building (locale, canonical, status, redirect, indexability, raw/rendered, source method).
-
Connected the non-canonical hreflang check to Google's same-language canonical-preference guidance and noted crawl output is diagnostic, not proof of Google's final selection.
-
Added Google's documented caveat that third-party hreflang debugging tools aren't maintained or checked by Google, and a raw-artifact confirmation step, in the Advanced, Tools, and Anti-Patterns lenses.
Full comparison unavailable — no prior snapshot was archived for this revision.