ytdl-org/youtube-dl · error · ExtractorError
Unable to login: %s
Error message
Unable to login: %s
What it means
Raised by PluralsightIE._login when the login POST response contains a '<span class="field-validation-error">' element. The span's text (ASP.NET-style validation message, e.g. 'The Email field is required' or 'Invalid login attempt') is interpolated: 'Unable to login: <error>'. Expected=True.
Source
Thrown at youtube_dl/extractor/pluralsight.py:198
})
post_url = self._search_regex(
r'<form[^>]+action=(["\'])(?P<url>.+?)\1', login_page,
'post url', default=self._LOGIN_URL, group='url')
if not post_url.startswith('http'):
post_url = compat_urlparse.urljoin(self._LOGIN_URL, post_url)
response = self._download_webpage(
post_url, None, 'Logging in',
data=urlencode_postdata(login_form),
headers={'Content-Type': 'application/x-www-form-urlencoded'})
error = self._search_regex(
r'<span[^>]+class="field-validation-error"[^>]*>([^<]+)</span>',
response, 'error message', default=None)
if error:
raise ExtractorError('Unable to login: %s' % error, expected=True)
if all(not re.search(p, response) for p in (
r'__INITIAL_STATE__', r'["\']currentUser["\']',
# new layout?
r'>\s*Sign out\s*<')):
BLOCKED = 'Your account has been blocked due to suspicious activity'
if BLOCKED in response:
raise ExtractorError(
'Unable to login: %s' % BLOCKED, expected=True)
MUST_AGREE = 'To continue using Pluralsight, you must agree to'
if any(p in response for p in (MUST_AGREE, '>Disagree<', '>Agree<')):
raise ExtractorError(
'Unable to login: %s some documents. Go to pluralsight.com, '
'log in and agree with what Pluralsight requires.'
% MUST_AGREE, expected=True)
raise ExtractorError('Unable to log in')
View on GitHub (pinned to 956b8c5855)
Solutions
- Verify credentials at app.pluralsight.com/id/ in a browser; reset password if needed
- Use --cookies with an exported logged-in session instead of password login
- Wait and retry if repeated attempts locked the account
Example fix
# before youtube_dl --username me@example.com --password 'typo' PS_URL # after youtube_dl --cookies cookies.txt PS_URL # session exported from logged-in browser
Defensive patterns
Strategy: validation
Validate before calling
# Prove credentials work in a browser first; then smoke-test: yt-dlp --username "$PS_USER" --password "$PS_PASS" --simulate ONE_URL \ || echo 'Login rejected — fix credentials before batch'
Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
if e.expected and str(e).startswith('Unable to login:'):
sys.exit('Pluralsight: ' + str(e)) # message is the validation text Prevention
- Reset stale passwords; keep .netrc current
- Use --cookies to bypass form-login fragility
- Read the interpolated validation message — it states the exact field problem
When it happens
Trigger: Submitting the login form and Pluralsight's server-side validation fails: wrong email/password, empty fields, or anti-forgery token mismatch (stale form scrape). Detected by regex over the response HTML.
Common situations: Typo'd credentials in .netrc; password changed since stored; login form requiring reCAPTCHA so plain POST is rejected; account locked after repeated failures.
Related errors
- Unable to login: %s some documents. Go to pluralsight.com, l
- Unable to login: %s
- self._parse_json(e.cause.read(), None)['errorMessage']
- %s said: %s
- Unable to log in
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/af6e674ddd6d5eaa.
Report an issue: GitHub.