ytdl-org/youtube-dl · error · ExtractorError
parsed JSON ['message'] from HTTP 400/401/403 response body
Error message
parsed JSON ['message'] from HTTP 400/401/403 response body (dynamic)
What it means
Raised by Zype extractors when the request to the .json variant of the video URL fails with HTTP 400, 401, or 403. The response body is parsed as JSON and its 'message' field is re-raised as an expected ExtractorError, surfacing the provider's own explanation (invalid video, unauthorized, forbidden).
Source
Thrown at youtube_dl/extractor/zype.py:51
}
@staticmethod
def _extract_urls(webpage):
return [
mobj.group('url')
for mobj in re.finditer(
r'<script[^>]+\bsrc=(["\'])(?P<url>(?:https?:)?%s.+?)\1' % (ZypeIE._COMMON_RE % ZypeIE._ID_RE),
webpage)]
def _real_extract(self, url):
video_id = self._match_id(url)
try:
response = self._download_json(re.sub(
r'\.(?:js|html)\?', '.json?', url), video_id)['response']
except ExtractorError as e:
if isinstance(e.cause, compat_HTTPError) and e.cause.code in (400, 401, 403):
raise ExtractorError(self._parse_json(
e.cause.read().decode(), video_id)['message'], expected=True)
raise
body = response['body']
video = response['video']
title = video['title']
if isinstance(body, dict):
formats = []
for output in body.get('outputs', []):
output_url = output.get('url')
if not output_url:
continue
name = output.get('name')
if name == 'm3u8':
formats = self._extract_m3u8_formats(
output_url, video_id, 'mp4',
'm3u8_native', m3u8_id='hls', fatal=False)View on GitHub (pinned to 956b8c5855)
Solutions
- Open the page in a browser and confirm the video still plays without a login
- If the video needs a subscription/login, use --username/--password or the site's supported auth flow
- For geo blocks, retry from an allowed network (with --proxy if appropriate)
- Update youtube-dl in case the Zype endpoint or auth scheme changed
Defensive patterns
Strategy: try-catch
Try / catch
try:
ydl.download([url])
except ExtractorError as e:
# e.msg is the provider's own message from the 400/401/403 body
if 'unauthorized' in str(e).lower():
attach_credentials_and_retry(url)
else:
raise Prevention
- Verify Zype embed URLs still play in a browser before batch processing
- Supply subscription credentials where the publisher requires login
- Log the dynamic message verbatim — it distinguishes deleted/forbidden/geo cases
When it happens
Trigger: Downloading a Zype-hosted video (zype.com or an embedded player using the Zype JSON endpoint) where the API rejects the request: deleted/private video id, missing or expired access credentials, or a geo/IP block.
Common situations: Embedded Zype players on publisher sites whose videos require a subscription or login; expired embed URLs; publisher removed the video but the page still embeds the player.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/9412f7946f996f61.
Report an issue: GitHub.