yt-dlp/yt-dlp · error · ExtractorError
Unsupported language code: {preferred_lang}. Supported langu
Error message
Unsupported language code: {preferred_lang}. Supported language codes (case-sensitive): {join_nonempty(*self._SUPPORTED_LANG_CODES, delim=", ")}. What it means
YoutubeBaseInfoExtractor._preferred_lang (a functools.cached_property) validates the youtube:lang extractor argument against the hard-coded _SUPPORTED_LANG_CODES list using casesense=True. Any code not in that list aborts extraction immediately with expected=True, and the error message prints the full supported list. Codes like 'en', 'de', 'pt-PT', 'zh-CN', 'ja' are valid; near-misses like 'EN', 'pt-BR' (not listed), or 'zh' are not.
Source
Thrown at yt_dlp/extractor/youtube/_base.py:651
def handle_from_url(self, url):
return self._search_regex(rf'^(?:https?://(?:www\.)?youtube\.com)?/({self._YT_HANDLE_RE})',
urllib.parse.unquote(url or ''), 'channel handle', default=None)
def ucid_from_url(self, url):
return self._search_regex(rf'^(?:https?://(?:www\.)?youtube\.com)?/({self._YT_CHANNEL_UCID_RE})',
url, 'channel id', default=None)
@functools.cached_property
def _preferred_lang(self):
"""
Returns a language code supported by YouTube for the user preferred language.
Returns None if no preferred language set.
"""
preferred_lang = self._configuration_arg('lang', ie_key='Youtube', casesense=True, default=[''])[0]
if not preferred_lang:
return
if preferred_lang not in self._SUPPORTED_LANG_CODES:
raise ExtractorError(
f'Unsupported language code: {preferred_lang}. Supported language codes (case-sensitive): {join_nonempty(*self._SUPPORTED_LANG_CODES, delim=", ")}.',
expected=True)
elif preferred_lang != 'en':
self.report_warning(
f'Preferring "{preferred_lang}" translated fields. Note that some metadata extraction may fail or be incorrect.')
return preferred_lang
def _initialize_consent(self):
if self._has_auth_cookies:
return
socs = self._youtube_cookies.get('SOCS')
if socs and not socs.value.startswith('CAA'): # not consented
return
self._set_cookie('.youtube.com', 'SOCS', 'CAI', secure=True) # accept all (required for mixes)
def _initialize_pref(self):
pref_cookie = self._youtube_cookies.get('PREF')
pref = {}View on GitHub (pinned to 81ecd58b13)
Solutions
- Re-run with a code taken verbatim from the error message's supported list (e.g. youtube:lang=pt-PT, youtube:lang=zh-CN, youtube:lang=en-GB)
- Check exact casing: 'en' not 'EN', 'zh-CN' not 'zh-cn'
- Update yt-dlp; the supported-codes list changes over releases and newer builds may accept your code
- Drop the lang argument entirely if you do not need translated metadata
Example fix
# before yt-dlp --extractor-args "youtube:lang=pt-BR" "https://www.youtube.com/watch?v=..." # -> Unsupported language code: pt-BR. ... # after yt-dlp --extractor-args "youtube:lang=pt-PT" "https://www.youtube.com/watch?v=..."
Defensive patterns
Strategy: validation
Validate before calling
from yt_dlp.extractor.youtube._base import YoutubeBaseInfoExtractor
lang = 'pt-PT' # value you intend to pass as youtube:lang
if lang not in YoutubeBaseInfoExtractor._SUPPORTED_LANG_CODES:
raise ValueError(
f'{lang!r} unsupported; pick one of: {YoutubeBaseInfoExtractor._SUPPORTED_LANG_CODES}') Prevention
- Treat youtube:lang values as case-sensitive exact tokens; copy them from the error message or the _SUPPORTED_LANG_CODES list in the installed version
- Prefer whole-language codes ('pt', 'en') over regional variants unless you need the variant
- Smoke-test new configs with --simulate before long runs
When it happens
Trigger: Running any YouTube extraction while --extractor-args youtube:lang=CODE is set and CODE is misspelled, wrong case (the check is case-sensitive), or a variant the list does not contain (e.g. 'pt-BR', 'nb', 'zh'). The property is cached, so the very first URL touching it fails.
Common situations: Copy-pasting a locale from elsewhere (BCP-47 with wrong region), assuming case-insensitivity, using an OS locale name instead of YouTube's list, or running an old yt-dlp whose supported list predates newly added codes.
Related errors
- No player clients have been requested
- Invalid bitrate(s): {", ".join(invalid_bitrates)}. Valid bit
- Invalid extractor-arg "tab". Must be one of {", ".join(self.
- '{selected_api}' is not a valid API selection
- Unsupported API client "{client}" requested. Supported clien
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/fe58c1171edd039e.
Report an issue: GitHub.