ytdl-org/youtube-dl · error · ExtractorError
Unable to login: %s
Error message
Unable to login: %s
What it means
Raised by FrontendMastersBaseIE._login when the POST of the WordPress login form succeeds HTTP-wise but the response contains neither the logout marker nor a parseable MessageAlert error. The '%s' variant appears when an error banner WAS found; a separate bare 'Unable to log in' covers the unparseable case. Expected=True variant means bad credentials or an account issue surfaced by the site.
Source
Thrown at youtube_dl/extractor/frontendmasters.py:69
'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'})
# Successful login
if any(p in response for p in (
'wp-login.php?action=logout', '>Logout')):
return
error = self._html_search_regex(
r'class=(["\'])(?:(?!\1).)*\bMessageAlert\b(?:(?!\1).)*\1[^>]*>(?P<error>[^<]+)<',
response, 'error message', default=None, group='error')
if error:
raise ExtractorError('Unable to login: %s' % error, expected=True)
raise ExtractorError('Unable to log in')
class FrontendMastersPageBaseIE(FrontendMastersBaseIE):
def _download_course(self, course_name, url):
return self._download_json(
'%s/courses/%s' % (self._API_BASE, course_name), course_name,
'Downloading course JSON', headers={'Referer': url})
@staticmethod
def _extract_chapters(course):
chapters = []
lesson_elements = course.get('lessonElements')
if isinstance(lesson_elements, list):
chapters = [url_or_none(e) for e in lesson_elements if url_or_none(e)]
return chapters
@staticmethodView on GitHub (pinned to 956b8c5855)
Solutions
- Verify the exact username/password by logging in at frontendmasters.com in a browser
- Ensure the account has an active subscription (free accounts cannot download course videos)
- Quote credentials properly on the command line to avoid shell mangling of special characters
- If the site now requires captcha/2FA, log in via browser and use --cookies instead of --username/--password
Example fix
# before youtube_dl --username me@example.com --password 'wronpw' 'https://frontendmasters.com/courses/x/' # ERROR: Unable to login: Invalid username or password # after yt-dlp --username me@example.com --password 'correctpw' 'https://frontendmasters.com/courses/x/' # or yt-dlp --cookies fm_cookies.txt 'https://frontendmasters.com/courses/x/'
Defensive patterns
Strategy: try-catch
Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
if 'Unable to login' in str(e):
alert_credentials_invalid(e) # check --username/--password; do not loop retries Prevention
- Store FrontendMasters credentials in netrc to avoid shell-quoting mistakes
- If 2FA/captcha blocks password login, switch to --cookies from a browser session
When it happens
Trigger: The login response lacks 'wp-login.php?action=logout' and '>Logout', and the regex class="...MessageAlert...">(?P<error>...)< matches — the site displayed an error such as 'Invalid username' or 'incorrect password'. Occurs with wrong --username/--password or an account without an active FrontendMasters subscription.
Common situations: Typo'd credentials in CI configs; expired subscription accounts; password changes not reflected in stored CLI options; 2FA/captcha interstitials that look like login failures to the regex.
Related errors
- error
- Unable to log in
- The video is not available, Facebook said: "%s"
- Cannot download file. Are you logged in?
- This video is only available via cable service provider subs
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/a11fbafbbf0d7df9.
Report an issue: GitHub.