Hreflang Mistakes That Kill International SEO
Ten errors account for almost every broken hreflang setup, and most of them fail silently. Here is how to spot each one and correct it.
Most hreflang problems come down to ten mistakes: missing return links, no self-reference, invalid language or region codes, relative URLs, pointing at non-canonical pages, a missing x-default, mixed implementation methods, partial coverage, blocked alternates, and treating hreflang as a duplicate content fix. Each has a clear symptom and a specific fix.
What hreflang actually does
hreflang tells search engines which language or regional version of a page to show a given user. It swaps the URL in the result and nothing more. It is not a ranking boost. A page with flawless annotations still has to earn its position on its own merits.
What a correct hreflang set looks like
Three versions, English, Spanish and a fallback, written as link elements in the head of every one of those pages:
<link rel="alternate" hreflang="en" href="https://example.com/page/">
<link rel="alternate" hreflang="es" href="https://example.com/es/pagina/">
<link rel="alternate" hreflang="x-default" href="https://example.com/page/">
The same relationship expressed in an XML sitemap, where the urlset has to declare the xhtml namespace:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/page/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/page/"/>
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/pagina/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/page/"/>
</url>
</urlset>
The Spanish page carries the identical set. That symmetry is the entire mechanism, and most of the mistakes below are ways of breaking it.
1. Missing return links
Every hreflang relationship is bidirectional. If A points at B, B must point back at A, or the annotation is unconfirmed and ignored. Symptom: versions never swap in results, and Search Console reports no return tags. Fix: generate the same complete set for every page in the group, not a one-way list.
2. No self-referencing hreflang
Each page must include an hreflang entry for its own URL. Leaving it out makes the set incomplete, and engines discard sets they cannot reconcile. Fix: add the self-reference, so a three-language group carries three entries on all three pages.
3. Wrong language and region codes
The language value must be an ISO 639-1 code and the optional region must be ISO 3166-1 Alpha 2. A region can never stand alone. Three classic errors: en-UK instead of en-GB, confusing zh-CN (Chinese in China) with zh-Hans (a script subtag, not a region), and inventing a language out of a country, like uk for Britain when it means Ukrainian. Invalid values are dropped without warning.
4. Relative URLs
hreflang values must be fully qualified absolute URLs, protocol included. A value like /es/pagina/ is invalid and the entry is skipped. Symptom: annotations that look right in your template but never register anywhere. Fix: emit https://example.com/es/pagina/ every time, the same rule that applies to sitemap loc values.
5. Pointing at non-canonical, redirecting or noindexed URLs
hreflang and canonical have to agree. Each page's canonical points at itself, and every hreflang value points at another version's canonical URL. Annotating a URL that redirects, canonicalises elsewhere or is noindexed sends contradictory instructions, and the conflict usually resolves by dropping your annotations. Fix: make sure each URL in the group returns 200, is indexable and is self-canonical.
6. Missing or misused x-default
x-default marks the fallback for users whose language you do not cover: a language selector, a global landing page, or your primary version. Symptom: visitors from uncovered locales landing on an arbitrary version. Fix: name one genuine fallback and repeat it across the whole group.
7. Mixing implementation methods
There are three valid places for hreflang: HTML link elements in the head, HTTP Link headers, and xhtml:link annotations in the XML sitemap. Any one works. Trouble starts when a site half-implements two, so the head lists two languages while the sitemap lists four. Pick one method and be complete in it.
8. Annotating only the homepage
hreflang is a page-level signal, not a site-level setting. Tagging the homepage does nothing for the 500 product pages underneath it. Symptom: the right homepage per market, deeper pages in the wrong language. Fix: pair every page with its true equivalents, and where no equivalent exists, leave that language out rather than pointing at a near match.
9. Blocking the alternate so it cannot be crawled
A relationship is only confirmed if both pages are fetchable. Disallowing a language folder in robots.txt, or gating it behind geo-redirects that bounce crawlers, breaks the return link check. Fix: keep every annotated URL crawlable and reachable without a redirect.
10. Expecting hreflang to fix duplicate content
hreflang manages regional and language variants. It does not deduplicate near-identical pages and it is no substitute for canonical tags. Two almost identical English pages, one for the US and one for Australia, still compete with each other; hreflang only says which market each is meant for. Genuine duplicates need canonicalisation or consolidation.
Which implementation method to use
| Method | Best for | Main downside |
|---|---|---|
| HTML link elements in head | HTML pages, few languages, template-driven sites | Markup grows with the square of the language count and ships on every page load |
| HTTP Link header | Non-HTML files such as PDFs, where there is no head to edit | Invisible in view source, needs server or CDN config, easy to lose on a migration |
| XML sitemap xhtml:link | Large sites and many languages; keeps page markup lean | Harder to spot-check, and the sitemap has to stay valid and current or the whole set goes stale |
The sitemap route scales best, which is also why it fails quietly: a malformed namespace or a stale file takes the annotations with it. Validate the sitemap after any generator change, and split large multilingual sets with a sitemap index.
How to check hreflang is working
Check in both directions. Fetch page A, read its annotation set, then fetch every URL it names and confirm each lists the same set including itself. View source covers the HTML method, response headers cover the second, and the sitemap covers the third. Any asymmetry is the bug.
Where Search Console offers international targeting reporting for your property, it lists hreflang errors such as missing return tags and unknown language codes, which is the fastest way to see problems at scale. It lags behind your deploys, so treat it as a second opinion. For the crawl-level faults underneath, the sitemap error guide covers the redirects, 404s and robots.txt blocks that take annotation sets down.