Skip to main content
SiteScan.top

hreflang: the tag that breaks quietly and stays broken

Why language annotations must be reciprocal, the three errors that make them useless, and how to verify a multilingual site without opening every page.

SEO · Published: 2 September 2026 · 3 min read · Ольга Мирошник

A multilingual site has a specific failure mode: everything looks right in every language, and the wrong version ranks in every country. The cause is almost always hreflang — a tag nobody sees, nobody tests, and everybody copies from a template.

What it is for

hreflang does not decide which page ranks. It tells a search engine that several pages are the same content in different languages, so the engine can swap in the version that matches the user. Get it right and your German visitor lands on the German page instead of the English one. Get it wrong and the engine falls back to guessing.

The shape is unremarkable:

<link rel="alternate" hreflang="en" href="https://site.com/page/">
<link rel="alternate" hreflang="de" href="https://site.com/de/page/">
<link rel="alternate" hreflang="x-default" href="https://site.com/page/">

The rule that catches everyone

Annotations must be reciprocal. If the English page lists the German one, the German page must list the English one back — and both must list themselves. A one-way annotation is ignored entirely, which is why a site can be full of correct-looking tags that do nothing.

This is also why hreflang breaks during ordinary work. Someone adds a fourth language and updates three templates instead of four. Someone deletes a page and its former siblings keep pointing at it. Nothing errors, nothing looks different, and the annotation set silently stops being valid.

Three errors, in order of frequency

Pointing at redirects or 404s. The target must be the final URL, with a 200. A link to an address that redirects wastes the annotation.

Wrong codes. The language is ISO 639-1, the optional region is ISO 3166-1 Alpha-2, and the order is language-then-region: en-GB, not gb-en. en-UK is not a country code. A bare de covers every German speaker; use de-AT only when the content genuinely differs.

Missing x-default. Without it the engine has no instruction for visitors who match none of your languages. The x-default should point at your language selector or your most general version.

Verifying without opening every page

The check is mechanical, which means it should never be manual:

for each page:
  collect its alternates
  for each alternate:
    does it return 200?
    does it point back at this page?
    is the code well-formed?
    is there exactly one x-default in the set?

Run it on a crawl of the whole site. On a site with four languages and a thousand pages that is four thousand relationships — a list no human maintains by hand, and precisely the kind of thing that stays broken for a year because nobody has a reason to look.

One more consistency check

The lang attribute on <html> should agree with the hreflang for that page, and the canonical of each language version should point at itself, not at the English original. Those two mistakes together produce the classic symptom: the English page ranking in every market, and the translated pages appearing nowhere at all.

Read next

Check how much of this is on your own site

A free scan surfaces broken links, JS errors and performance problems in about a minute.