ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

RedBullTVIE.extract_info requests a session from api.redbull.tv/v3/session and raises ExtractorError('%s said: %s' % (IE_NAME, session['message'])) when the response JSON has code == 'error'. The interpolated message is Red Bull's own explanation (e.g. service unavailable / region issues). Not marked expected=True, so it surfaces as an unexpected failure. This is the gate before the token is used for product and stream requests.

Source

Thrown at youtube_dl/extractor/redbulltv.py:65

        'url': 'https://www.redbull.com/us-en/events/AP-1XV2K61Q51W11/live/AP-1XUJ86FDH1W11',
        'only_matching': True,
    }, {
        'url': 'https://www.redbull.com/int-en/films/AP-1ZSMAW8FH2111',
        'only_matching': True,
    }, {
        'url': 'https://www.redbull.com/int-en/episodes/AP-1TQWK7XE11W11',
        'only_matching': True,
    }]

    def extract_info(self, video_id):
        session = self._download_json(
            'https://api.redbull.tv/v3/session', video_id,
            note='Downloading access token', query={
                'category': 'personal_computer',
                'os_family': 'http',
            })
        if session.get('code') == 'error':
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, session['message']))
        token = session['token']

        try:
            video = self._download_json(
                'https://api.redbull.tv/v3/products/' + video_id,
                video_id, note='Downloading video information',
                headers={'Authorization': token}
            )
        except ExtractorError as e:
            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 404:
                error_message = self._parse_json(
                    e.cause.read().decode(), video_id)['error']
                raise ExtractorError('%s said: %s' % (
                    self.IE_NAME, error_message), expected=True)
            raise

        title = video['title'].strip()

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Retry after a short wait — session issuance failures are often transient.
  2. Update youtube-dl / yt-dlp; Red Bull TV endpoint version bumps are handled in newer releases.
  3. Test https://api.redbull.tv/v3/session?category=personal_computer&os_family=http directly to see the current response shape.
  4. If behind a VPN, try a different egress region in case token issuance is region-filtered.
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight the session endpoint before a batch run
import requests
r = requests.get('https://api.redbull.tv/v3/session',
                 params={'category': 'personal_computer', 'os_family': 'http'})
session_ok = r.ok and r.json().get('code') != 'error'

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if 'RedBullTV said:' in str(e) and 'session' in str(e).lower():
        backoff_and_retry(url, attempts=3)

Prevention

When it happens

Trigger: The v3/session endpoint (queried with category=personal_computer&os_family=http) returns {'code': 'error', 'message': ...} — service outages, API contract changes, or regional blocking of token issuance. Everything downstream (products/<id> with Authorization header, dms.redbull.tv m3u8) depends on this token, so failure here aborts all Red Bull TV extraction.

Common situations: Red Bull API maintenance or v3 deprecation after an extractor release; transient 5xx-ish responses shaped as code=error; unusual client IPs (VPNs) triggering session refusal.

Related errors


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