Key takeaways
- hreflang is only honoured when it is reciprocal; if page X points to page Y, Y must point back to X, or Google ignores the whole pair
- Every page must also list itself in its own hreflang set, a self-referencing tag Google requires and one of the easiest tags to accidentally drop
- Language codes must be valid ISO 639-1 (optionally with an ISO 3166-1 region), never a country code on its own
- Auditing this one page at a time misses the real failure mode, because a broken pair is invisible from either page in isolation; you need the whole cluster checked together
Hreflang tags are easy to get subtly, invisibly wrong. A single missing return link and Google silently ignores the whole pair, no warning, no error message, just two pages competing against each other in search instead of each ranking cleanly in its own market. This is what actually breaks, how to find it across a whole site rather than one page at a time, and exactly how to fix each failure mode.
What hreflang is for, in one sentence
Hreflang tags tell search engines which page to show for a given language or region, so your /en-gb/ page and your /fr-fr/ page don't compete with each other for the same query in the same country's search results. Get it right and each version ranks in its own market. Get it wrong and Google, faced with ambiguity, ignores the annotation entirely and falls back to picking whichever version it judges best, which is rarely the outcome you wanted.
The four ways hreflang actually breaks
Most explanations of hreflang describe the tag's syntax and stop there. The syntax is the easy part. What actually causes real sites to lose out is one of four specific failure modes:
1. Missing return (reciprocal) links
This is the big one, and Google is explicit about the rule: "If page X links to page Y, page Y must link back to page X." Hreflang is only honoured when it is two-way. A cluster of five regional pages needs the return link correct on all five; add a sixth region months later and forget to update the other five, and the whole cluster's reciprocity breaks for the page nobody remembered to touch, not just the new one.
Note
This is what makes hreflang fragile in a way most other SEO tags aren't. A missing title tag only affects the one page missing it. A missing hreflang return tag can silently break a working relationship between two other pages that looked fine individually.
2. No self-referencing tag
Google's documentation states it plainly: "Each language version must list itself as well as all other language versions." A page's own hreflang set needs an entry pointing at itself, alongside the entries for every other language or region version. It's an easy tag to drop, because it feels redundant to link a page to itself, but Google requires it and a set missing it is incomplete even when every other entry is correct.
3. Invalid language or region codes
Hreflang codes follow a specific format: an ISO 639-1 language code, optionally paired with an ISO 3166-1 Alpha-2 region code, joined by a hyphen (en-GB, fr-CA). Two mistakes account for most of the invalid codes we see:
- A region code used alone. Google is direct about this: "you can't specify the country code by itself."
USon its own is not a valid hreflang value; it needs a language, as inen-US. - Non-standard or malformed values. Codes like
en_US(underscore instead of hyphen),english, or a country/language pairing that doesn't exist are all silently invalid, and Google's stated response to a set containing errors is that "those annotations may be ignored or not interpreted correctly": not one bad tag ignored in isolation, the reliability of the whole set called into question.
x-default is the one reserved exception. It's used for visitors who don't match any of your other language or region tags, typically pointing at a language selector or a sensible default version, and it doesn't need a reciprocal return link the way a genuine language alternate does.
4. Alternates pointing at non-indexable URLs
An hreflang entry that points at a URL which 404s, redirects, carries a noindex tag, or declares a canonical pointing at a different URL cannot do its job: hreflang is meant to connect indexable, canonical versions of a page, and a target that isn't indexable can't reasonably be expected to hold up its end of the reciprocal link either. This one is easy to miss by eye, because the tag itself looks perfectly well-formed; the problem is entirely in what it points at.
How to find hreflang errors across a whole site
Here's the part that catches people out: you cannot reliably audit hreflang by reading one page's <head> at a time. A single page's own hreflang set can look completely correct in isolation while the actual fault sits on a different page it references, one that simply never links back. The failure is a property of the pair, not of either page alone, so checking pages one at a time will pass exactly the cases that matter most.
1. Crawl the whole cluster together. Crawl Cove's hreflang checker crawls every page's hreflang annotations and cross-references them across the whole site at once: missing return (reciprocal) tags, invalid language or region codes, and alternates pointing at URLs that 404, redirect, or aren't indexable. Because it reconciles the full cluster rather than one URL, it catches the reciprocity failures that a page-by-page read misses entirely.
Note
Reciprocity and target checks can only be confirmed for pages the crawl actually reached. An alternate pointing at an external domain, or a page outside the crawl, can't be validated either way, so it's left alone rather than guessed at, the same honest limit Crawl Cove applies to its other whole-site checks.
2. Spot-check a single URL when you already suspect it. If a client flags one specific page, our free single-URL tool checks that URL against the alternates it names (up to 20) without needing a full crawl: each alternate's HTTP status, whether it is noindexed or canonicalised to another URL, and whether it links back, plus any tag written as a relative URL rather than a full one. It's fast for confirming a single relationship, but it only sees a cluster as wide as that one page's own tags describe, so it can't discover a page that should be in the cluster but isn't referenced from anywhere.
The two are complementary, not interchangeable: the single-URL tool is for confirming a suspicion, the full crawl is for finding the failures nobody thought to check yet.
See the full drawer mechanics in The Evidence Drawer.
How to fix each failure mode
- Missing return link: add the missing reciprocal
hreflangentry on the target page. Check every page in the cluster, not just the two you already suspect, since one page changing without the others being updated is the usual cause. - Missing self-reference: add an entry on the page pointing at itself, alongside its existing alternates.
- Invalid code: correct it to a valid ISO 639-1 language code, optionally with an ISO 3166-1 region (
en-GB, noten_GBorGBalone). - Alternate targets a non-indexable URL: either fix the target so it resolves to a real, indexable page (undo an accidental
noindex, name the final URL rather than one that redirects, point the target's canonical at itself), or remove that entry from the set if the target genuinely shouldn't be there any more.
Fix these on the whole cluster, not just the page you started from. Because a return-link failure only shows up on the other page, working through fixes one URL at a time and stopping as soon as the page you're looking at is clean will leave the pages it references still broken.
Wrap-up
Hreflang fails quietly, and the specific way it fails matters: a missing return link, a missing self-reference, an invalid code, or an alternate pointing somewhere non-indexable. All four can look fine when you read a single page's tags in isolation, because the fault often sits on the other end of the relationship. Auditing hreflang for real means checking the whole cluster together, not reading one <head> at a time, then correcting the specific failure mode you found rather than guessing at a fix. Get reciprocity right across every page in the cluster and each language or region version can finally rank cleanly in its own market instead of quietly cancelling each other out.
Frequently asked questions
- What does it mean when hreflang tags are not reciprocal?
- It means page A names page B as an alternate, but page B does not name page A back. Google's own guidance is direct: "If page X links to page Y, page Y must link back to page X." When that reciprocity is missing, Google ignores the annotation rather than guessing at your intent, so neither page benefits from it.
- What is a self-referencing hreflang tag?
- It is an entry in a page's own hreflang set that points at itself, alongside the entries for its other language or region versions. Google's documentation states plainly that "each language version must list itself as well as all other language versions", so a set missing this is incomplete even if every other tag is correct.
- What is a valid hreflang language code?
- An ISO 639-1 language code, optionally followed by a hyphen and an ISO 3166-1 Alpha-2 region code, such as en-GB or fr-CA. A region code cannot be used on its own; Google is explicit that "you can't specify the country code by itself."
- What is x-default in hreflang?
- A reserved value used for visitors whose language or region does not match any of your other tags, typically pointing at a language selector or a default version of the page. It does not need a reciprocal return link the way a language-specific alternate does.
- Can I check hreflang errors one page at a time?
- You can spot-check a single page's own tags that way, but the failure that actually costs traffic is usually on the OTHER end: a page that is referenced by your cluster but does not point back. That is invisible unless you check the whole cluster together, which is what a full-site crawl is for.