ytdl-org/youtube-dl · error · ExtractorError
message
Error message
message
What it means
Raised in BrightcoveNewIE's policy-key retry loop when the playback API answers 401/403. The body is parsed as JSON and the message is json_data.get('message') or json_data['error_code']. Before re-raising it handles two special cases: error_subcode CLIENT_GEO raises a geo-restricted error, and error_code INVALID_POLICY_KEY with a freshly extracted policy key clears the cached key and retries once.
Source
Thrown at youtube_dl/extractor/brightcove.py:656
for _ in range(2):
if not policy_key:
policy_key = extract_policy_key()
policy_key_extracted = True
headers['Accept'] = 'application/json;pk=%s' % policy_key
try:
json_data = self._download_json(api_url, video_id, headers=headers)
break
except ExtractorError as e:
if isinstance(e.cause, compat_HTTPError) and e.cause.code in (401, 403):
json_data = self._parse_json(e.cause.read().decode(), video_id)[0]
message = json_data.get('message') or json_data['error_code']
if json_data.get('error_subcode') == 'CLIENT_GEO':
self.raise_geo_restricted(msg=message)
elif json_data.get('error_code') == 'INVALID_POLICY_KEY' and not policy_key_extracted:
policy_key = None
store_pk(None)
continue
raise ExtractorError(message, expected=True)
raise
errors = json_data.get('errors')
if errors and errors[0].get('error_subcode') == 'TVE_AUTH':
custom_fields = json_data['custom_fields']
tve_token = self._extract_mvpd_auth(
smuggled_data['source_url'], video_id,
custom_fields['bcadobepassrequestorid'],
custom_fields['bcadobepassresourceid'])
json_data = self._download_json(
api_url, video_id, headers={
'Accept': 'application/json;pk=%s' % policy_key
}, query={
'tveToken': tve_token,
})
if content_type == 'playlist':
return self.playlist_result(View on GitHub (pinned to 956b8c5855)
Solutions
- Clear the cached policy key: youtube-dl --no-cache-dir (or remove the cache directory) and retry so a fresh key is scraped from the player page.
- If the error is geo related (CLIENT_GEO shows as geo-restricted), use --proxy or run from an allowed country.
- Update to yt-dlp for current policy-key extraction logic.
- Confirm the account/player id in the URL is correct — wrong ids commonly produce 401/403 JSON errors.
Example fix
# before
ydl.extract(url) # 403 INVALID_POLICY_KEY from stale cache
# after
from youtube_dl import YoutubeDL
with YoutubeDL({'no-cache-dir': True}) as ydl:
ydl.extract(url) Defensive patterns
Strategy: retry
Try / catch
from youtube_dl.utils import ExtractorError, GeoRestrictedError
try:
info = ydl_no_cache.extract_info(url, download=False)
except GeoRestrictedError:
info = ydl_with_proxy.extract_info(url, download=False)
except ExtractorError as e:
if 'POLICY_KEY' in str(e): # retry once with a cold cache
info = YoutubeDL({'no_cache-dir': True}).extract_info(url, download=False)
else:
raise Prevention
- Run with --no-cache-dir when Brightcove sites rotate policy keys.
- Distinguish GeoRestrictedError from plain ExtractorError in callers.
- Verify account/player id correctness before extraction.
When it happens
Trigger: HTTP 401/403 from the playback API where the JSON error is neither CLIENT_GEO nor a first-time INVALID_POLICY_KEY — e.g. an API key/typo'd policy key, an expired token, or access-control rejection. CLIENT_GEO produces a GeoRestrictedError instead; persistent INVALID_POLICY_KEY after one retry falls through to this raise.
Common situations: Stale cached policy key in youtube-dl's cache after the site rotated keys; extracting from a region the account blocks; running an old youtube-dl against a changed Brightcove API.
Related errors
- %s
- Cannot find player ID
- Unsupported URL: %s
- error.get('message') or error.get('error_subcode') or error[
- This video is DRM protected.
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/9040214ff730a58c.
Report an issue: GitHub.