ytdl-org/youtube-dl · error · ExtractorError
error['description']
Error message
error['description']
What it means
Raised by TV2IE (Norwegian tv2.no) when the play.json API returns HTTP 401 and the parsed error is neither 'ASSET_PLAYBACK_INVALID_GEO_LOCATION' (which raises geo-restricted) nor 'SESSION_NOT_AUTHENTICATED' (which raises login-required). The error's 'description' field is re-raised verbatim (NOT expected=True).
Source
Thrown at youtube_dl/extractor/tv2.py:66
title = asset.get('subtitle') or asset['title']
is_live = asset.get('live') is True
formats = []
format_urls = []
for protocol in self._PROTOCOLS:
try:
data = self._download_json(
api_base + '/play.json?protocol=%s&videoFormat=SMIL+ISMUSP' % protocol,
video_id, 'Downloading play JSON')['playback']
except ExtractorError as e:
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
error = self._parse_json(e.cause.read().decode(), video_id)['error']
error_code = error.get('code')
if error_code == 'ASSET_PLAYBACK_INVALID_GEO_LOCATION':
self.raise_geo_restricted(countries=self._GEO_COUNTRIES)
elif error_code == 'SESSION_NOT_AUTHENTICATED':
self.raise_login_required()
raise ExtractorError(error['description'])
raise
items = try_get(data, lambda x: x['items']['item'])
if not items:
continue
if not isinstance(items, list):
items = [items]
for item in items:
if not isinstance(item, dict):
continue
video_url = item.get('url')
if not video_url or video_url in format_urls:
continue
format_id = '%s-%s' % (protocol.lower(), item.get('mediaFormat'))
if not self._is_valid_url(video_url, video_id, format_id):
continue
format_urls.append(video_url)
ext = determine_ext(video_url)
if ext == 'f4m':View on GitHub (pinned to 956b8c5855)
Solutions
- Read the description text — it states the actual refusal (DRM, subscription, expired)
- If subscription content, log in via browser and pass cookies (yt-dlp --cookies-from-browser chrome)
- If geo-related per the description, use a Norwegian exit IP
- Update to yt-dlp for current TV2 handling
Defensive patterns
Strategy: try-catch
Try / catch
try:
ydl.extract_info(tv2_url)
except ExtractorError as e:
if 'ASSET_PLAYBACK' in str(e) or 'DRM' in str(e):
mark_premium_or_drm(url, str(e))
elif 'SESSION_NOT_AUTHENTICATED' in str(e) or 'login' in str(e):
retry_with_cookies(tv2_url) Prevention
- Read the description field — it distinguishes DRM, subscription, and geo cases
- For Sumo content, log in via browser and reuse cookies
- Use a Norwegian IP for Norway-licensed media
- Note this error is not expected=True, so catch broadly on message content
When it happens
Trigger: Extracting a tv2.no video whose /play.json returns 401 with some other code — commonly 'ASSET_PLAYBACK_INVALID_DEVICE_DRM', expired asset, or content requiring the TV2 Sumo subscription — after the extractor already fell back across protocols (hls/dash).
Common situations: Premium Sumo content accessed without a subscription; device-type DRM restrictions; Norway-only licensing; API changes after TV2's player updates that older extractors don't map.
Related errors
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/cc23f66dfd46e4a2.
Report an issue: GitHub.