yt-dlp/yt-dlp · error · ExtractorError
Unable to login: {credentials}
Error message
Unable to login: {credentials} What it means
The O'Reilly/Safari login POSTs email/password to the auth API (an HTTP 400 response is tolerated). If the response says logged_in=false, has no redirect_uri, and includes a 'credentials' object, that object carries the server's failure text and is surfaced as 'Unable to login: <credentials>' (expected=True).
Source
Thrown at yt_dlp/extractor/safari.py:53
qs = urllib.parse.parse_qs(parsed_url.query)
next_uri = urllib.parse.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(
f'Unable to login: {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 81ecd58b13)
Solutions
- Verify the email/password by logging in at learning.oreilly.com in a browser
- If your account is organizational/SSO-only, password login cannot work — use an account with a native password
- Re-enter credentials carefully (quote them properly in the shell)
- Update yt-dlp in case the auth endpoint changed
Defensive patterns
Strategy: try-catch
Try / catch
from yt_dlp.utils import ExtractorError
try:
info = ydl.extract_info(url, download=True)
except ExtractorError as e:
if e.expected and 'Unable to login:' in str(e):
# O'Reilly's own rejection (wrong password / SSO-only account)
raise SystemExit(f'O\'Reilly rejected the login: {e}')
raise Prevention
- Verify email/password at learning.oreilly.com before scripting
- Know whether your account is SSO-only — those cannot use password login
- Keep credentials in .netrc and update them when the site password changes
When it happens
Trigger: Running a safari/oreilly extractor with --username/--password where O'Reilly rejects the pair: the auth API answers 400 with {'logged_in': false, 'credentials': {...}} — wrong password, unknown email, or an account without a native password.
Common situations: Wrong or expired password; accounts that authenticate only via organization SSO (no native password exists); stale .netrc credentials.
Related errors
- Unable to log in
- Invalid login credentials
- Login failed
- invalid username/password
- Unable to login: Invalid password
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/1cbab5d0b3633f21.
Report an issue: GitHub.