ytdl-org/youtube-dl · error · ExtractorError

error (parsed JSON 'Message' from 401 response)

Error message

error (parsed JSON 'Message' from 401 response)

What it means

Raised by TouTvIE (Radio-Canada) during login when the OAuth token request returns HTTP 401; the extractor parses the JSON body and re-raises its 'Message' field (e.g. invalid credentials). Expected=True, so it is reported as an authentication failure with the server's own text.

Source

Thrown at youtube_dl/extractor/toutv.py:63

        if email is None:
            return
        try:
            self._access_token = self._download_json(
                'https://services.radio-canada.ca/toutv/profiling/accounts/login',
                None, 'Logging in', data=json.dumps({
                    'ClientId': self._CLIENT_KEY,
                    'ClientSecret': '34026772-244b-49b6-8b06-317b30ac9a20',
                    'Email': email,
                    'Password': password,
                    'Scope': 'id.write media-validation.read',
                }).encode(), headers={
                    'Authorization': 'client-key ' + self._CLIENT_KEY,
                    'Content-Type': 'application/json;charset=utf-8',
                })['access_token']
        except ExtractorError as e:
            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
                error = self._parse_json(e.cause.read().decode(), None)['Message']
                raise ExtractorError(error, expected=True)
            raise
        self._claims = self._call_api('validation/v2/getClaims')['claims']

    def _real_extract(self, url):
        path = self._match_id(url)
        metadata = self._download_json(
            'https://services.radio-canada.ca/toutv/presentation/%s' % path, path, query={
                'client_key': self._CLIENT_KEY,
                'device': 'web',
                'version': 4,
            })
        # IsDrm does not necessarily mean the video is DRM protected (see
        # https://github.com/ytdl-org/youtube-dl/issues/13994).
        if metadata.get('IsDrm'):
            self.report_warning('This video is probably DRM protected.', path)
        video_id = metadata['IdMedia']
        details = metadata['Details']

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Verify the username/password on the tou.tv website in a browser
  2. Prefer cookie-based auth: export cookies after browser login and use --cookies (yt-dlp), avoiding the legacy password flow entirely
  3. Update to yt-dlp, which dropped/reworked TouTV password login
  4. If you maintain a fork, refresh _CLIENT_KEY/ClientSecret from the current website requests

Example fix

# before: password login hits 401 and surfaces the raw Message
yt-dlp --username USER --password PASS URL
# after: reuse an authenticated browser session
yt-dlp --cookies-from-browser firefox URL
Defensive patterns

Strategy: fallback

Try / catch

try:
    ydl.download([url])
except ExtractorError as e:
    if e.expected and e.cause_is_401():
        # fall back to cookie-based session instead of password login
        run(['yt-dlp', '--cookies-from-browser', 'firefox', url])

Prevention

When it happens

Trigger: Passing --username/--password for a touvieres canadien account where the token endpoint at services.radio-canada.ca returns 401: wrong password, changed client key/secret, or the R&C auth API rejecting the legacy login flow.

Common situations: Typos in credentials; expired/changed accounts; Radio-Canada migrating auth so the hardcoded ClientSecret no longer validates; older youtube-dl versions predating fixes to the TouTV login flow.

Related errors


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