ytdl-org/youtube-dl · error · ExtractorError

Unable to login: %s

Error message

Unable to login: %s

What it means

Raised by the Safari Books/O'Reilly login helper when the auth API response (requested with expected_status=400) has logged_in false, no redirect_uri, and a 'credentials' payload - i.e. the server rejected the credentials and told you why. Message: 'Unable to login: <credentials text>'. Expected=True.

Source

Thrown at youtube_dl/extractor/safari.py:67

        qs = compat_parse_qs(parsed_url.query)
        next_uri = compat_urlparse.urljoin(
            'https://api.oreilly.com', qs['next'][0])

        auth, urlh = self._download_json_handle(
            'https://www.oreilly.com/member/auth/login/', None, 'Logging in',
            data=json.dumps({
                'email': username,
                'password': password,
                'redirect_uri': next_uri,
            }).encode(), headers={
                'Content-Type': 'application/json',
                'Referer': redirect_url,
            }, expected_status=400)

        credentials = auth.get('credentials')
        if (not auth.get('logged_in') and not auth.get('redirect_uri')
                and credentials):
            raise ExtractorError(
                'Unable to login: %s' % credentials, expected=True)

        # oreilly serves two same instances of the following cookies
        # in Set-Cookie header and expects first one to be actually set
        for cookie in ('groot_sessionid', 'orm-jwt', 'orm-rt'):
            self._apply_first_set_cookie_header(urlh, cookie)

        _, urlh = self._download_webpage_handle(
            auth.get('redirect_uri') or next_uri, None, 'Completing login',)

        if is_logged(urlh):
            self.LOGGED_IN = True
            return

        raise ExtractorError('Unable to log in')


class SafariIE(SafariBaseIE):

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Re-enter username/password carefully (the credentials text from the server names the exact problem).
  2. Reset the password on oreilly.com if it expired.
  3. Verify the account has access to the content being downloaded.
  4. Clear stored cookies for the site and retry so the login POST is clean.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if str(e).startswith('Unable to login:'):
        fix_credentials(e)  # server message names the credential problem
    else:
        raise

Prevention

When it happens

Trigger: Running youtube-dl with --username/--password against oreilly/safaribooksonline where the email/password JSON POST returns 400 plus a credentials error (wrong password, unknown email).

Common situations: Typos in credentials, expired passwords, or accounts without video entitlement; also stale cookies interleaving with the login POST.

Related errors


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