Hreflang Reciprocity Checker Free Tool
Paste your hreflang alternates one per line as page-url | lang-code | alternate-url to check every rel=alternate hreflang return tag at once. Google only trusts hreflang when the links are reciprocal — if page A says page B is its alternate, page B must point back to A. This tool flags missing return tags (the target page is in your set but never links back) and broken targets (an alternate pointing to a URL you did not include). A page with several language alternates is entered as several lines that share the same page-url. x-default is allowed. This is a read-only report; nothing on your site is changed.
About Hreflang Reciprocity Checker
What Hreflang Tags Actually Do
An hreflang tag (rel="alternate" hreflang="x") is a small piece of markup that tells search engines which URL to show a searcher based on the language or region they're searching from. It doesn't translate anything and it doesn't redirect anyone automatically. It's a signal, not a mechanism: "if this person is searching in Spanish from Spain, this other URL is the version meant for them."
A simple example makes it concrete. Say a site publishes the same page in two versions, an English one at https://example.com/en/ and a Spanish one at https://example.com/es/. Without hreflang, Google has no reliable way to know these two URLs are the same content aimed at different audiences, it might show either one to either searcher, or treat them as unrelated duplicate-ish pages competing against each other. With hreflang tags declared correctly, Google can serve https://example.com/es/ to someone searching in Spanish from Spain and https://example.com/en/ to someone searching in English, instead of guessing.
The tag itself usually lives in the <head> of a page, one line per language alternate: <link rel="alternate" hreflang="es" href="https://example.com/es/" />. A page with several language versions declares several of these tags, one per alternate, and it also normally declares one pointing at itself. Hreflang can also live in an XML sitemap instead of in-page <link> tags, both are valid per Google's international and multi-language documentation, and both follow the exact same reciprocity rule covered next.
Hreflang codes combine a language code with an optional region code, es for Spanish generally, es-ES for Spanish as spoken in Spain specifically, es-MX for Spanish as spoken in Mexico. Getting the code right matters, but it's a separate problem from the one this tool checks. This tool isn't validating whether es-ES is a well-formed code, it's checking something that trips up sites with otherwise perfectly formed codes: whether the pages actually link back to each other the way Google requires.
The Reciprocity Rule: Why a One-Way Hreflang Link Doesn't Work
This is the part of hreflang that causes the most real-world breakage, and it's worth stating plainly before anything else: Google requires the relationship between two hreflang-linked pages to be confirmed from both sides. If page A declares an hreflang alternate pointing to page B, page B must declare an alternate pointing back to page A. This is a documented requirement in Google Search Central's guidance on hreflang implementation, not an informal best practice.
The reason is straightforward once you think about how a crawler encounters these tags. Google can't just trust a one-sided claim, page A saying "page B is my Spanish version" doesn't prove anything about page B on its own; anyone could put that tag on any page pointing at any URL. What confirms the relationship is page B saying something back, that it, too, considers page A one of its language alternates. Two pages agreeing with each other is a reciprocal, confirmed relationship. One page claiming a relationship the other page never mentions is not.
In practice, that means a one-way hreflang link is effectively ignored by Google. Not partially honored, not treated as a weaker signal, ignored. Google can't verify a relationship it only sees evidence of from one direction, so it doesn't act on it. This is the single rule most worth understanding before troubleshooting any hreflang problem, and it's the exact rule this tool checks for automatically across however many pages you paste in.
One detail surprises people who assume otherwise, so it's worth being precise about it: the return tag doesn't need to use a matching language code to count as reciprocal. What Google actually checks is that the URLs point back to each other, not that the codes on both sides are identical. A page tagged hreflang="es" pointing at a target, and that target pointing back with any hreflang code at all as long as the URL matches, still counts as reciprocal. The classification this tool runs mirrors that exact rule, matching by URL, not by requiring the lang codes on each side to line up.
The Three Ways a Declared Hreflang Alternate Can Resolve
Every hreflang alternate you submit to this tool lands in exactly one of three states. These are the exact three categories the tool itself uses, so understanding them here means the results table won't need any translation later.
Reciprocal: the healthy state
An alternate is reciprocal when the target page is present in your submitted set, and that target page declares an alternate pointing back to the origin URL. This is the confirmed, working relationship described above, both sides agree, Google can act on the signal. Reciprocal is the only state that requires no follow-up action.
Missing return tag: the target exists but never links back
An alternate has a missing return tag when the target page is present in your submitted set, but that target page's own declared alternates never include a URL pointing back to the origin page. The target is real, it's part of your set, it just doesn't reciprocate. This is the state most worth fixing first for pages you know are live and intended to be part of the cluster, because the fix is usually a single missing tag on one page rather than anything structural.
Broken target: the target isn't in your set at all
An alternate has a broken target when the URL it points to isn't present anywhere in the set of pages you submitted. In practice this usually means one of a few things: the target URL was mistyped, the target page was moved or deleted without updating the hreflang tags that referenced it, or you simply didn't include that page in this particular audit run and it does exist on your live site. The False Positives section further down covers how to tell those apart before assuming every broken row is a confirmed site problem.
| State | What it means | Action needed |
|---|---|---|
| Reciprocal | Target exists in your set and links back to the origin | None, this is healthy |
| Missing return tag | Target exists in your set but never links back | Add the missing alternate on the target page |
| Broken target | Target isn't in your submitted set at all | Confirm whether the URL is real, fix or remove the tag |
Understanding x-default
x-default is a special hreflang value, not a real language or region code. It declares a fallback page for visitors whose language or region doesn't match any of the other alternates you've explicitly listed, commonly a language-selector page, or a default version a site wants to show anyone outside its targeted languages.
It's one of the more commonly confused parts of the hreflang spec, mostly because it looks like it should behave like a language code but represents something different: a catch-all rather than a specific audience. A cluster with English, Spanish, and French versions might add a fourth entry, x-default, pointing at whichever page should show to a searcher in, say, Japanese or Portuguese, languages the site hasn't built a dedicated version for.
For the purposes of this tool, x-default is treated exactly like any other lang-code token, it participates in the same reciprocity check as every other alternate. If a page declares an x-default alternate pointing at another page, that target page needs an alternate pointing back, the same rule that applies to es, fr, or any other code. There's no special exemption for it in the reciprocity requirement, a one-way x-default link gets ignored by Google the same as any other one-way hreflang link would.
Common Causes of Broken Hreflang Reciprocity
Broken reciprocity is almost never a deliberate choice, it accumulates from a handful of recurring, mundane causes:
- Adding a new language version and updating only one page. A site launches a new German version of a page that already had English and Spanish versions. The English page gets updated to add a German alternate, but the Spanish page and the German page itself never get the corresponding updates, leaving the new page with no return tags pointing to it from anywhere except the one page someone remembered to edit.
- Template or CMS bugs that don't propagate updates across the full set. Some content management systems generate hreflang blocks from a per-page field rather than deriving them dynamically from an actual language-group relationship. When that's the case, updating one page's language group doesn't automatically update every other page in that group, and pages quietly drift out of sync with each other over time.
- Manual copy-paste errors on sites with many language pairs. A site with five or six language versions per page has a lot of alternates to keep straight by hand. It's easy to paste the wrong target URL, transpose a lang-code, or copy an old block forward during a template rebuild and forget to update every URL in it.
- Migrations and URL restructuring. When a site moves to new URL patterns, hreflang tags referencing the old structure sometimes get missed by the same migration script that correctly updated canonicals or internal links, leaving stale targets that no longer resolve to the current page.
- Deleting or unpublishing one language version without cleaning up references to it. If a site retires a regional version of a page, every other page in that cluster that still declares an alternate pointing at the retired URL now has a broken target until those references get removed too.
Nearly all of these share a pattern: one page in the cluster changes, and the corresponding change on every related page doesn't happen automatically. That's exactly why hreflang tends to break quietly, and why re-auditing after any language-related change is worth doing rather than assuming one correct edit was enough.
The Multi-Language Cluster Rule: Every Page Must Link to Every Other Page
A common and understandable mistake: treating one language version as the "primary" page and having every other version link only to that primary page and back, rather than to each other. This is a hub-and-spoke pattern, and it doesn't satisfy reciprocity for every pair in the cluster, only for the pairs that include the hub.
Reciprocity is a per-pair requirement, not a per-cluster one. For a cluster of three or more languages, every page needs to declare an alternate for every other page in that cluster, and every one of those alternates needs a return tag from the page it points to. A full mesh, not a hub with spokes.
A worked example makes this concrete. Say a page exists in three languages: https://example.com/en/, https://example.com/es/, and https://example.com/fr/. If the site sets up the English page as the hub, both the Spanish and French pages declare alternates pointing to the English page, and the English page declares alternates pointing to both of them, that satisfies reciprocity for the English-Spanish pair and the English-French pair.
But if the Spanish page never declares an alternate pointing to the French page, and the French page never declares one pointing to the Spanish page, that Spanish-French pair has no relationship declared at all, not broken, not missing a return tag, simply never declared. Once someone does add a one-way link between them, say the Spanish page gets an alternate pointing to French without the French page reciprocating, that pair now shows up as a genuine missing-return-tag problem.
The complete, correct version of that three-page cluster: each of the three pages declares two alternates, one for each of the other two pages, for a total of six declared alternates across the cluster (plus each page typically also self-references). Every page ends up reciprocal with every other page, not just with the one designated as primary. This is exactly the pattern this tool is built to verify at scale, pasting in every declared alternate across a cluster and confirming every pair actually reciprocates, not just the pairs involving whichever page someone assumed was the anchor.
What Happens When Hreflang Reciprocity Is Broken
None of this is about one stray missing tag quietly doing nothing. The real cost shows up in what Google does instead of honoring the intended signal.
A missing return tag or a broken target, as covered above, means Google can't confirm the relationship between the two pages, so it treats the hreflang signal for that pair as absent rather than partially trusted. The practical result is that the "wrong" language version can keep showing to searchers who should have been served the alternate. Someone searching in Spanish from Spain might keep seeing an English result instead of the Spanish page that was supposed to be served to them, simply because Google never received a confirmed signal telling it the Spanish page was the intended match.
There's a second, quieter effect. Without a confirmed hreflang relationship, two pages that are the same content translated into different languages can end up evaluated more like separate, unrelated pages than like a coordinated multi-language set. That can surface in Google Search Console's International Targeting report as unconfirmed or ignored hreflang entries, and in more general terms as a kind of duplicate-content-across-languages confusion, where the intended coordination between language versions simply isn't recognized.
Be realistic about scope here too. A single missing return tag on one page pair in an otherwise healthy cluster is a small, fixable gap, not a site-wide penalty. The real risk is at scale: a systemic cause, like a template bug that never propagates updates, quietly breaking reciprocity across dozens or hundreds of page pairs at once, each one individually small but collectively meaning a meaningful share of a site's international traffic is landing on the wrong language version far more often than it should.
How the Hreflang Reciprocity Checker Works
This tool is a report-only auditor. It never fetches a live page, never crawls your site, and never changes an hreflang tag anywhere, it only reads and classifies whatever you paste in.
The input format is one hreflang alternate per line, written as page-url | lang-code | alternate-url. Because a page usually declares several language alternates, a page with, say, four language versions is entered as four separate lines that all share the same page-url, one line per alternate. x-default is accepted as a valid lang-code, same as any real language code.
Before classification, the tool applies a few practical limits and cleanup steps: it accepts up to 20,000 raw input lines and audits up to 5,000 distinct pages among them, with a cap of 500 alternates per single page. It skips any line that isn't exactly three pipe-separated parts, or where either URL isn't a real absolute http:// or https:// address, or where the lang-code doesn't look like a valid code, and it tells you how many lines were skipped. It removes duplicate alternates, the same page-url and lang-code declared twice, keeping the first occurrence. Individual URL tokens are capped at 2,048 characters and lang-codes at 35 characters, so an accidentally pasted wall of text doesn't choke the audit.
Once the input is cleaned, every declared alternate gets checked against the full submitted set. If the target page isn't anywhere in that set, the alternate is broken. If the target page is in the set, the tool looks at that target's own declared alternates and checks whether any of them point back to the origin URL, matching by URL only, not requiring the lang-codes on both sides to match, exactly the rule covered earlier. If a return tag is found, the alternate is reciprocal. If the target exists but no return tag points back, it's a missing return tag.
What you get back is a summary line showing how many alternates and pages were audited, plus how many lines were skipped or deduplicated, a row of three colored count labels, and a results table listing every submitted alternate with its origin page, lang-code, target, and status. Broken rows get a short inline note that the target wasn't in your submitted list, missing-return-tag rows get a note that the target page doesn't link back. Nothing about this process writes to your site, fetches a live URL, or changes an actual hreflang tag, it's strictly read-only reporting on the data you provide.
One important limitation worth knowing before you paste a list: the tool audits exactly the set of pages and alternates you give it, it doesn't independently fetch anything from your live site. If you already have the hreflang data, from a crawler export, a CMS report, a sitemap, or manual view-source checks, the audit is only as accurate as that source data. It confirms relationships between the URLs and lang-codes you supply, it isn't separately verifying that a page's live HTML still matches what you typed in.
False Positives: When "Broken" or "Missing" Doesn't Mean Actually Broken
Because the tool only classifies the exact set of alternates you paste in, a target can show up as broken simply because you didn't include that page in this particular batch, not because it's genuinely missing from your live site. If you audit a sample of 30 pages out of a cluster spanning your whole site, an alternate pointing at a page outside that sample will show as broken in that run even if the page exists and reciprocates correctly, it just wasn't part of the set you submitted.
The practical fix for this is straightforward: before treating a broken row as a confirmed site problem, check whether the target URL is a real, live page. If it is, add its own declared alternates to your next audit run so the tool can see the full relationship, if it genuinely doesn't exist or was retired, that's a confirmed broken hreflang tag worth cleaning up.
Missing return tags deserve a similar sanity check when the target page is one you don't fully control, syndicated content on a partner domain, for example. If the target page belongs to someone else's site and you can't add a return tag to it yourself, that pair effectively can never satisfy reciprocity, and hreflang isn't the right mechanism for that relationship at all; that's a case for a canonical tag pointing at the original instead, covered in the comparison section below.
How to Use This Tool
- Gather the hreflang alternates you want to check, from a crawler export, a CMS hreflang report, an XML sitemap, or manual view-source checks on each page in the cluster.
- List every declared alternate one per line. A page with several language versions needs several lines, all sharing that page's own URL.
- Format each line as
page-url | lang-code | alternate-url, using the full absolute URL on both sides. - Paste the complete list into the textarea on this page.
- Submit the form. The audit runs immediately, there's nothing to configure beyond the submission itself.
- Read the summary line first, showing how many alternates and pages were audited, plus any lines skipped as invalid or removed as duplicates.
- Open the results table and focus first on rows marked missing return tag or broken target, those are the two states Google won't honor as-is.
Reading Your Results Table
The results table has four columns, each showing a different piece of the same audit rather than repeating what the summary already told you.
From page is the origin URL for that declared alternate, exactly as you submitted it. hreflang is the lang-code on that specific line, including x-default where used. Points to (alternate) is the target URL that alternate declares.
Status is one of the three states covered above, reciprocal needs no action, missing return tag and broken target do. Rows marked broken carry a small note that the target wasn't found anywhere in your submitted list; rows marked missing return tag carry a note that the target page exists but doesn't link back, pointing you toward the exact page that needs a tag added rather than leaving you to guess.
A quick worked example helps make the table concrete. Say you paste three lines: https://example.com/en/ | es | https://example.com/es/, https://example.com/es/ | en | https://example.com/en/, and https://example.com/en/ | fr | https://example.com/fr/, without a fourth line for https://example.com/fr/ declaring anything back to English.
The first row shows reciprocal, because the Spanish page's own alternate points back to the English page. The second row also shows reciprocal, the same pair confirmed from the other direction. The third row shows missing return tag if https://example.com/fr/ was included elsewhere in the paste without an alternate pointing back to English, or broken target if https://example.com/fr/ wasn't included in the paste at all. Add a fourth line, https://example.com/fr/ | en | https://example.com/en/, and that third row flips to reciprocal on the next audit.
How to Fix Broken Hreflang Reciprocity Once You Find It
- Add the missing return tag directly on the target page. A missing-return-tag row tells you exactly which page is missing an alternate and which URL it needs to point to, the fix is usually one added line in that page's hreflang block, not a structural change.
- Confirm every page in a multi-language cluster links to every other page, not just to one primary page. Revisit the full-mesh rule covered above for any cluster of three or more languages, and check specifically for pairs that were never declared at all, not just pairs that show as broken or missing.
- Remove or correct alternates pointing at pages that no longer exist. If a broken target turns out to be genuinely gone, delete that alternate rather than leaving a stale reference in place for the next audit to keep flagging.
- Trace systemic issues back to the template or CMS setting responsible. If the same kind of gap shows up across many page pairs at once, fixing the underlying template or content-model logic that generates hreflang blocks fixes every affected page in one pass, rather than patching pages one at a time.
- Don't try to force reciprocity onto pages you don't control. If the intended target is on a domain you can't edit, hreflang isn't the right tool for that relationship, a canonical tag pointing at the original is usually the correct mechanism instead.
- Re-run the checker after fixing. Paste the same set of alternates back through the tool once changes are live to confirm the previously flagged rows now show reciprocal, and that no fix accidentally left a different pair without a return tag.
Fixing a single missing return tag is usually a small edit once you know exactly which page needs it, the harder part is almost always finding every gap across a cluster with more than a handful of language pairs. That's the specific gap this tool is built to close.
Hreflang vs. Canonical: Not Competing Signals
Hreflang and canonical tags get confused often enough to be worth a direct comparison, because on the surface they can look like they're doing something similar, telling search engines about a relationship between URLs, and in practice they solve opposite problems.
A canonical tag picks ONE master URL among duplicate or near-duplicate pages and tells search engines to consolidate ranking signals onto that single URL. It's a "these are the same, treat only one as real" signal. Hreflang does the opposite: it tells search engines that several URLs are DIFFERENT, deliberately different, intended for different audiences, and it should show each one to the audience it was built for rather than picking a single winner. Using a canonical tag across language versions of the same page would actively work against hreflang's purpose, it would tell search engines to treat the Spanish and English versions as duplicates of one master page instead of two intentionally distinct versions meant for different searchers.
Where the two tools on this site pair up naturally: the Canonical Conflict Auditor checks whether a site's canonical tags correctly resolve to one clean master URL per set of duplicates, the same way this tool checks whether hreflang alternates correctly resolve to a confirmed, reciprocal relationship per language pair. Both are "confirm the paired relationship actually works both ways or resolves cleanly" auditors, just applied to a different kind of tag with a different intended outcome.
Related Tools
Hreflang problems on multi-language sites often show up alongside a couple of other technical-SEO issues worth checking at the same time.
- Multi-language sites frequently reuse the same template across locales without fully differentiating it, which can produce duplicate title tags and meta descriptions across language versions, the Duplicate Meta Finder checks for that related symptom.
- If a broken hreflang target turns out to be a page that got moved rather than deleted, the Redirect Chain Checker can confirm whether the old URL is forwarding cleanly to its new address, useful context before deciding whether to update the hreflang tag or just leave the redirect in place.
Frequently Asked Questions
What does "reciprocal" mean in my results?
It means the target page you pointed an alternate at is in your submitted set, and that target page has its own alternate pointing back to the origin page. See the three-state breakdown above for the full definitions.
What's the difference between missing return tag and broken target?
Missing return tag means the target page IS in your submitted set but doesn't link back. Broken target means the target page isn't in your submitted set at all. Covered in detail in the three-state section above.
Does x-default need a return tag too?
Yes. This tool treats x-default the same as any real language code, if a page declares an x-default alternate pointing at another page, that page needs a return tag pointing back for the pair to count as reciprocal.
Does this tool crawl my site or fetch live hreflang tags?
No. It's strictly read-only. You paste hreflang alternates as page/lang/target triples, it classifies them, nothing on your site is fetched, crawled, or modified at any point.
How many pages and alternates can I check at once?
Up to 5,000 distinct pages get audited per submission, from up to 20,000 raw input lines, with a cap of 500 alternates per single page. Duplicate page-plus-lang-code entries are automatically removed before those limits apply.
Does hreflang reciprocity affect my canonical tags?
No, they're separate signals solving different problems. Canonical picks one master URL among duplicates; hreflang serves different URLs to different audiences. See the comparison section above for the full distinction.