About This HTML Issue
The hreflang attribute on a link element tells browsers and search engines the language and optional region of the linked resource. Its value must be a valid BCP 47 language tag, which follows a specific structure: a primary language subtag (like en, fr, de) optionally followed by a region subtag (like US, GB, FR). The region subtag must be a valid two-letter ISO 3166-1 alpha-2 country code.
The tag en-EN is invalid because EN is not a recognized country code. There is no country with the code “EN” — it’s a common mistake where the language code is simply repeated as the region. This pattern shows up frequently with other languages too, such as fr-FR (which happens to be valid because FR is the country code for France) leading people to assume en-EN follows the same logic. However, EN is not assigned to any country in ISO 3166-1, so the validator correctly rejects it.
Why This Matters
-
SEO and internationalization: Search engines like Google use
hreflangvalues to serve the correct localized version of a page. An invalid value may cause search engines to ignore the tag entirely, undermining your localization strategy. - Standards compliance: Browsers and tools rely on well-formed language tags to apply correct locale-specific behavior such as font selection, date formatting hints, and spell-checking language.
- Accessibility: Screen readers and assistive technologies may use language information to select the correct speech synthesis voice. Invalid language tags can lead to content being read in the wrong accent or language.
Common Invalid Region Subtags
This mistake isn’t limited to English. Here are some commonly seen invalid patterns and their corrections:
| Invalid | Why It’s Wrong | Valid Alternatives |
|---|---|---|
en-EN |
EN is not a country code |
en, en-US, en-GB, en-AU |
de-DE |
✅ Actually valid — DE is Germany |
de, de-DE, de-AT, de-CH |
ja-JA |
JA is not a country code |
ja, ja-JP |
zh-ZH |
ZH is not a country code |
zh, zh-CN, zh-TW |
ko-KO |
KO is not a country code |
ko, ko-KR |
The key takeaway: don’t assume you can double the language code to make a region subtag. Always verify against the ISO 3166-1 alpha-2 country code list.
How to Fix It
-
If you don’t need a regional variant, just use the bare language subtag:
en. -
If you need a specific regional variant, pair the language subtag with the correct country code:
en-USfor American English,en-GBfor British English,en-AUfor Australian English, etc. - Look up the country code if you’re unsure. The region subtag corresponds to a country, not a language.
Examples
Incorrect — Invalid region subtag
<link rel="alternate" href="https://example.com/en/" hreflang="en-EN">
The region subtag EN does not correspond to any country and will trigger a validation error.
Correct — Language only
If the content is simply in English without a specific regional variant, omit the region:
<link rel="alternate" href="https://example.com/en/" hreflang="en">
Correct — Language with valid region subtags
When you need to differentiate between regional variants, use proper country codes:
<link rel="alternate" href="https://example.com/en-us/" hreflang="en-US">
<link rel="alternate" href="https://example.com/en-gb/" hreflang="en-GB">
<link rel="alternate" href="https://example.com/en-au/" hreflang="en-AU">
Correct — Full set of hreflang links with x-default
A typical multilingual setup with properly formed language tags:
<link rel="alternate" href="https://example.com/" hreflang="x-default">
<link rel="alternate" href="https://example.com/en/" hreflang="en">
<link rel="alternate" href="https://example.com/en-us/" hreflang="en-US">
<link rel="alternate" href="https://example.com/fr/" hreflang="fr">
<link rel="alternate" href="https://example.com/de/" hreflang="de">
<link rel="alternate" href="https://example.com/ja/" hreflang="ja">
Note the use of x-default to indicate the default or language-selection page — this is a special value recognized by search engines for fallback purposes.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.