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

  1. Open the page in a browser and confirm the video still plays without a login
  2. If the video needs a subscription/login, use --username/--password or the site's supported auth flow
  3. For geo blocks, retry from an allowed network (with --proxy if appropriate)
  4. 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

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

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/9412f7946f996f61. Report an issue: GitHub.