ytdl-org/youtube-dl · error · ExtractorError
%s
Error message
%s
What it means
Raised by the Limelight extractor when the PlaylistService API returns HTTP 403: the 403 body's detail.contentAccessPermission value is re-raised verbatim as the error message (with 'CountryDisabled' upgraded to a geo-restriction error). It is expected=True and encodes the publisher's access-permission refusal.
Source
Thrown at youtube_dl/extractor/limelight.py:79
smuggle('limelight:media:%s' % video_id),
LimelightMediaIE.ie_key(), video_id))
return entries
def _call_playlist_service(self, item_id, method, fatal=True, referer=None):
headers = {}
if referer:
headers['Referer'] = referer
try:
return self._download_json(
self._PLAYLIST_SERVICE_URL % (self._PLAYLIST_SERVICE_PATH, item_id, method),
item_id, 'Downloading PlaylistService %s JSON' % method,
fatal=fatal, headers=headers)
except ExtractorError as e:
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
error = self._parse_json(e.cause.read().decode(), item_id)['detail']['contentAccessPermission']
if error == 'CountryDisabled':
self.raise_geo_restricted()
raise ExtractorError(error, expected=True)
raise
def _extract(self, item_id, pc_method, mobile_method, referer=None):
pc = self._call_playlist_service(item_id, pc_method, referer=referer)
mobile = self._call_playlist_service(
item_id, mobile_method, fatal=False, referer=referer)
return pc, mobile
def _extract_info(self, pc, mobile, i, referer):
get_item = lambda x, y: try_get(x, lambda x: x[y][i], dict) or {}
pc_item = get_item(pc, 'playlistItems')
mobile_item = get_item(mobile, 'mediaList')
video_id = pc_item.get('mediaId') or mobile_item['mediaId']
title = pc_item.get('title') or mobile_item['title']
formats = []
urls = []
for stream in pc_item.get('streams', []):View on GitHub (pinned to 956b8c5855)
Solutions
- If the message says CountryDisabled, use a proxy in an allowed country
- If domain-restricted, open the video from the original embedding page (or pass its URL as Referer via --add-headers)
- Confirm the media id is still published in the publisher's Limelight dashboard
- Update to yt-dlp for improved Limelight handling
Example fix
# supply the embedding page as referer # yt-dlp --add-headers 'Referer:https://original-site.example/page' 'https://assets.delvenetworks.com/...'
Defensive patterns
Strategy: try-catch
Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
msg = str(e)
if 'CountryDisabled' in msg:
retry_with_regional_proxy(url)
elif 'DomainDisabled' in msg or 'PermissionDenied' in msg:
retry_with_referer(url, embedding_page_url)
else:
raise Prevention
- Pass the embedding page URL as Referer for domain-restricted Limelight embeds
- Match egress region to the publisher's licensing before extracting
When it happens
Trigger: Requesting a Limelight media/channel id whose PlaylistService call (playlist.<method>.json) responds 403 with a contentAccessPermission such as 'CountryDisabled', 'DomainDisabled', or expired/unpublished media — e.g. embeds restricted to the publisher's own domain or region.
Common situations: Videos restricted to specific domains (referrers) opened directly; geo-disabled media; unpublished or deleted channel items still referenced by old pages; missing Referer when the embed requires it.
Related errors
- %s returned error: %s
- %s said: %s
- %s said: %s
- The video is not available from your location
- Unable to load data. Error code: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/0d005f54f199a28c.
Report an issue: GitHub.