ytdl-org/youtube-dl · error · ExtractorError

', '.join([e['message'] for e in entitlement_issues])

Error message

', '.join([e['message'] for e in entitlement_issues])

What it means

Raised by the FOX extractor when a 403 from api2.fox.com lists entitlementIssues but NONE of them carries errorCode 1005. All issue messages are joined with ', ' and re-raised as an expected error. This covers every non-'cable subscription' entitlement rejection: not entitled to the specific show, device/session issues, or account-level restrictions.

Source

Thrown at youtube_dl/extractor/fox.py:78

            'X-Api-Key': self._API_KEY,
        }
        if self._access_token:
            headers['Authorization'] = 'Bearer ' + self._access_token
        try:
            return self._download_json(
                'https://api2.fox.com/v2.0/' + path,
                video_id, data=data, headers=headers)
        except ExtractorError as e:
            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
                entitlement_issues = self._parse_json(
                    e.cause.read().decode(), video_id)['entitlementIssues']
                for e in entitlement_issues:
                    if e.get('errorCode') == 1005:
                        raise ExtractorError(
                            'This video is only available via cable service provider '
                            'subscription. You may want to use --cookies.', expected=True)
                messages = ', '.join([e['message'] for e in entitlement_issues])
                raise ExtractorError(messages, expected=True)
            raise

    def _real_initialize(self):
        if not self._access_token:
            mvpd_auth = self._get_cookies(self._HOME_PAGE_URL).get('mvpd-auth')
            if mvpd_auth:
                self._access_token = (self._parse_json(compat_urllib_parse_unquote(
                    mvpd_auth.value), None, fatal=False) or {}).get('accessToken')
            if not self._access_token:
                self._access_token = self._call_api(
                    'login', None, json.dumps({
                        'deviceId': compat_str(uuid.uuid4()),
                    }).encode())['accessToken']

    def _real_extract(self, url):
        video_id = self._match_id(url)

        video = self._call_api('vodplayer/' + video_id, video_id)

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Read the joined messages — they state the actual entitlement problem (e.g. 'not entitled to content')
  2. Re-export fresh cookies from a browser where the show plays successfully
  3. Confirm the content's availability tier on fox.com and that your plan includes it
  4. Ensure a US IP, since geo failures can surface as entitlement issues on this API

Example fix

# before
youtube_dl --cookies old_cookies.txt 'https://www.fox.com/watch/some-show/'
# ERROR: not entitled to content, session expired

# after
# log in to fox.com in browser, verify playback, re-export cookies
youtube_dl --cookies fresh_cookies.txt 'https://www.fox.com/watch/some-show/'
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if 'entitlement' in str(e) or 'entitled' in str(e):
        log_and_alert_subscriber(e)  # surface joined messages to the user

Prevention

When it happens

Trigger: The 403 body parses successfully, the loop over entitlement_issues finds no errorCode 1005, and the joined 'message' fields are raised. Typical: a FOX account is authenticated but the content needs a different tier/package, the show is exclusive to another network, or the session token was rejected.

Common situations: Cookies from an account without the right package; FOX moving content to FOX One/FX+ tiers; stale access tokens after provider re-authentication.

Related errors


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