ytdl-org/youtube-dl · error · ExtractorError

error_msg (xpath_text(auth, 'error/msg'))

Error message

error_msg (xpath_text(auth, 'error/msg'))

What it means

Raised by the Turner (CNN/TBS/TNT/etc.) CVP tokenizer flow when the token XML contains a non-empty error/msg node (e.g. 'Media is not available', auth errors). Expected=True; the message text comes directly from the Akamai/tokenizer service response.

Source

Thrown at youtube_dl/extractor/turner.py:46

    def _add_akamai_spe_token(self, tokenizer_src, video_url, content_id, ap_data, custom_tokenizer_query=None):
        secure_path = self._search_regex(r'https?://[^/]+(.+/)', video_url, 'secure path') + '*'
        token = self._AKAMAI_SPE_TOKEN_CACHE.get(secure_path)
        if not token:
            query = {
                'path': secure_path,
            }
            if custom_tokenizer_query:
                query.update(custom_tokenizer_query)
            else:
                query['videoId'] = content_id
            if ap_data.get('auth_required'):
                query['accessToken'] = self._extract_mvpd_auth(ap_data['url'], content_id, ap_data['site_name'], ap_data['site_name'])
            auth = self._download_xml(
                tokenizer_src, content_id, query=query)
            error_msg = xpath_text(auth, 'error/msg')
            if error_msg:
                raise ExtractorError(error_msg, expected=True)
            token = xpath_text(auth, 'token')
            if not token:
                return video_url
            self._AKAMAI_SPE_TOKEN_CACHE[secure_path] = token
        return video_url + '?hdnea=' + token

    def _extract_cvp_info(self, data_src, video_id, path_data={}, ap_data={}, fatal=False):
        video_data = self._download_xml(
            data_src, video_id,
            transform_source=lambda s: fix_xml_ampersands(s).strip(),
            fatal=fatal)
        if not video_data:
            return {}
        video_id = video_data.attrib['id']
        title = xpath_text(video_data, 'headline', fatal=True)
        content_id = xpath_text(video_data, 'contentId') or video_id
        # rtmp_src = xpath_text(video_data, 'akamai/src')
        # if rtmp_src:

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Play the video on the origin site in a browser; if it demands a TV-provider login, authenticate in the browser and pass cookies (yt-dlp --cookies-from-browser)
  2. Update to yt-dlp, whose Turner/Adobe-TVE handling is actively maintained
  3. If geo-blocked, use an exit IP in the allowed region
  4. Catch expected ExtractorError in batch pipelines and record the server's msg verbatim for triage
Defensive patterns

Strategy: fallback

Try / catch

try:
    ydl.extract_info(turner_url)
except ExtractorError as e:
    if e.expected and any(k in str(e) for k in ('auth', 'entitled', 'geo', 'available')):
        if needs_tv_auth(str(e)):
            retry_with_cookies(turner_url)
        elif is_geo(str(e)):
            retry_with_us_exit(turner_url)

Prevention

When it happens

Trigger: Requesting a secure media path on a Turner property where the tokenizer (with optional accessToken from MVPD auth) responds with an <error><msg>...</msg></error> instead of a token: expired asset, geo restriction, or required TV-provider login (auth_required) that was not satisfied.

Common situations: TVE clips behind cable authentication; videos expired after their rights window; region restrictions; stale youtube-dl where the tokenizer query parameters (e.g. videoId vs custom query) no longer match the current Turner stack (now part of Warner Bros. Discovery).

Related errors


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