ytdl-org/youtube-dl · error · ExtractorError

error.get('message') or error.get('error_subcode') or error[

Error message

error.get('message') or error.get('error_subcode') or error['error_code']

What it means

Raised inside BrightcoveNewIE._real_extract when the playback API returned a JSON payload with an 'errors' array and no playable formats could be built. The message is errors[0].get('message') or error_subcode or error_code — i.e. the raw Brightcove Video Cloud error surfaced to the user. It is marked expected=True, so it is treated as a normal, user-facing failure rather than a bug.

Source

Thrown at youtube_dl/extractor/brightcove.py:547

                if src or streaming_src:
                    f.update({
                        'url': src or streaming_src,
                        'format_id': build_format_id('http' if src else 'http-streaming'),
                        'source_preference': 0 if src else -1,
                    })
                else:
                    f.update({
                        'url': app_name,
                        'play_path': stream_name,
                        'format_id': build_format_id('rtmp'),
                    })
                formats.append(f)

        if not formats:
            errors = json_data.get('errors')
            if errors:
                error = errors[0]
                raise ExtractorError(
                    error.get('message') or error.get('error_subcode') or error['error_code'], expected=True)
            if sources and num_drm_sources == len(sources):
                raise ExtractorError('This video is DRM protected.', expected=True)

        self._sort_formats(formats)

        for f in formats:
            f.setdefault('http_headers', {}).update(headers)

        subtitles = {}
        for text_track in json_data.get('text_tracks', []):
            if text_track.get('kind') != 'captions':
                continue
            text_track_url = url_or_none(text_track.get('src'))
            if not text_track_url:
                continue
            lang = (str_or_none(text_track.get('srclang'))
                    or str_or_none(text_track.get('label')) or 'en').lower()

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Verify the video still exists by opening the player URL in a browser.
  2. Make sure the account id in the URL matches the video's account (mismatched account/player pairs produce API errors).
  3. Update to yt-dlp so the current Brightcove API and policy-key extraction are used.
  4. If the message indicates geo restriction, retry from an allowed region or with a proxy (--proxy).

Example fix

try:
    info = ydl.extract_info(url, download=False)
except ExtractorError as e:
    # Brightcove API error text is in str(e); check for known subcodes
    if 'CLIENT_GEO' in str(e):
        info = ydl.extract_info(url, download=False, geo_bypass_country='US')
    else:
        raise
Defensive patterns

Strategy: try-catch

Try / catch

from youtube_dl.utils import ExtractorError
try:
    info = ydl.extract_info(url, download=False)
except ExtractorError as e:
    # e is expected=True; message is Brightcove's own API error text
    log_user_friendly('video unavailable: %s', e.msg)

Prevention

When it happens

Trigger: Calling the Brightcove playback API for a videoId whose JSON response contains a non-empty 'errors' list — typical causes: the video was deleted or is unpublished, the policy key does not authorize this video/account, or the video is geo-blocked. Only reached when 'formats' is empty after processing all sources.

Common situations: Expired or removed videos; using a policy key extracted from a different player/account than the video belongs to; CDN/API contract changes over time in this old extractor.

Related errors


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