Hreflang points to a non-canonical URL: alternates that redirect, are noindexed or canonicalise elsewhere
Hreflang tells Google which indexed page to show to which audience, so every URL in the set must be indexable in its own right: status 200, no noindex, and a canonical pointing at itself. An alternate that redirects or canonicalises elsewhere drops out of the set, usually taking its return link with it.
The classic version of this mistake is on translated pages. The French page is given a canonical to the English original "to avoid duplicate content", and from that moment the French page is asking not to be indexed while hreflang asks for it to be shown.
What it looks like
Before
<!-- on https://example.com/fr/tarifs/ -->
<link rel="canonical" href="https://example.com/pricing/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs/">
<link rel="alternate" hreflang="en" href="https://example.com/pricing/">
After
<!-- on https://example.com/fr/tarifs/ -->
<link rel="canonical" href="https://example.com/fr/tarifs/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs/">
<link rel="alternate" hreflang="en" href="https://example.com/pricing/">
Audit one set from the command line
This loop reads the hreflang URLs from a page and tests each for status, robots directives and canonical:
page=https://example.com/pricing/
curl -s "$page" | grep -io '<link[^>]*hreflang[^>]*>' | grep -o 'href="[^"]*"' | cut -d'"' -f2 | sort -u | while read u; do
code=$(curl -s -o /dev/null -w "%{http_code}" "$u")
canon=$(curl -s "$u" | grep -io '<link[^>]*rel=.canonical.[^>]*>' | grep -o 'href="[^"]*"' | cut -d'"' -f2)
robots=$(curl -s "$u" | grep -io '<meta[^>]*name=.robots.[^>]*>' | grep -io 'noindex')
echo "$code | $u | canonical: $canon | $robots"
done
A healthy line reads 200, shows a canonical equal to the URL itself, and has nothing in the last column. Anything else is one of the four faults below.
Fault 1: the alternate redirects
Hreflang lists https://example.com/de/preise and the server redirects it to /de/preise/. Or the tag still uses http://. Google needs the final URL in the annotation. Update the tags to the address that returns 200, and correct the setting that generates them, usually the language URL format or trailing-slash option in the multilingual plugin.
Automatic language redirection deserves a special mention. If the site sends visitors to a language version based on their browser language or IP address, Googlebot, which mostly crawls from the United States without a language preference, may be redirected away from the other versions and never see them. Offer a language switcher or a banner instead of forcing a redirect.
Fault 2: the alternate canonicalises to another page
Each language version must be its own canonical. Translations are not duplicates of each other; Google treats pages in different languages as different content. A canonical from every translation to the English page tells Google only the English page should be indexed, and the hreflang set collapses.
In WordPress, check three sources: a per-post canonical override that was copied when the translation was duplicated from the original; a multilingual plugin option that canonicalises translations to the default language; and a custom canonical filter. With Hydrogen SEO the default is a self-referencing canonical on every post, so look for a stale value in the Canonical URL field of the SEO Settings sheet on translated posts and clear it. More on overrides in canonical URLs.
The same fault appears with parameters. Hreflang pointing at /pricing/?lang=fr while that URL canonicalises to /pricing/ means the French version has no indexable URL of its own. Language versions need distinct URLs: subdirectories, subdomains or separate domains.
Fault 3: the alternate is noindexed or blocked
A noindex page cannot be shown, so it cannot be an alternate. This occurs when a language is launched in stages and the unfinished one is noindexed but already included in the tags, or when machine-translated pages are deliberately kept out of search. Remove such pages from every set until they are ready. A robots.txt block has the same effect, because Google cannot read the page's return tags.
Fault 4: the alternate does not exist
A 404 in the set comes from a translation that was deleted, unpublished or never created, while a template assumed every page exists in every language. Generate tags only for translations that are published. Do not substitute the language homepage: pointing the German alternate of your pricing page at /de/ claims that the German homepage is the German pricing page.
Rebuild the set consistently
After fixing the individual faults, each group of pages should satisfy all of these at once:
- Every member returns 200 and is indexable.
- Every member's canonical is its own URL.
- Every member prints the same list of alternates, including itself.
- URLs in the list match the canonical URLs exactly.
For hand-maintained sets, generate the block once with our hreflang tag generator and paste the same block into each version.
Re-run the audit on every language version
Run the audit loop from each language version and confirm every line is clean. In URL Inspection, test one translated page: the Google-selected canonical should be the inspected URL, not the default-language page. If it shows another language's URL, Google still regards the pages as duplicates, which can happen when a "translation" is mostly untranslated boilerplate. The free SEO audit confirms a canonical is present on each version and counts its hreflang tags, a quick first pass before the deeper check.
Common questions
Should translated pages canonicalise to the original language?
No. Each translation should have a self-referencing canonical. Canonicalising to the original asks Google not to index the translation.
Can hreflang point to a URL with parameters?
Only if that parameter URL is the canonical, indexable address for the language version. Clean, distinct URLs per language are far more reliable.
Does hreflang consolidate ranking signals like a canonical?
No. It only helps Google choose which version to show to which audience. Each version ranks on its own signals.
What if two regional pages have identical content?
Google may fold them together and index one. Hreflang can still swap the URL shown, but meaningful local differences, such as currency, spelling and contact details, make separate indexing more likely.