ytdl-org/youtube-dl · error · ExtractorError

Unable to login: %s

Error message

Unable to login: %s

What it means

Raised by TeachableBaseIE._login when the login POST went through (no privacy-policy marker) and is_logged(response) is false, but the response contains an element with class 'alert'. The alert's cleaned text (typically 'Invalid email or password' or 'account locked') is surfaced as 'Unable to login: <alert text>' with expected=True.

Source

Thrown at youtube_dl/extractor/teachable.py:98

            data=urlencode_postdata(login_form),
            headers={
                'Content-Type': 'application/x-www-form-urlencoded',
                'Referer': login_url,
            })

        if '>I accept the new Privacy Policy<' in response:
            raise ExtractorError(
                'Unable to login: %s asks you to accept new Privacy Policy. '
                'Go to https://%s/ and accept.' % (site, site), expected=True)

        # Successful login
        if is_logged(response):
            self._logged_in = True
            return

        message = get_element_by_class('alert', response)
        if message is not None:
            raise ExtractorError(
                'Unable to login: %s' % clean_html(message), expected=True)

        raise ExtractorError('Unable to log in')


class TeachableIE(TeachableBaseIE):
    _VALID_URL = r'''(?x)
                    (?:
                        %shttps?://(?P<site_t>[^/]+)|
                        https?://(?:www\.)?(?P<site>%s)
                    )
                    /courses/[^/]+/lectures/(?P<id>\d+)
                    ''' % TeachableBaseIE._VALID_URL_SUB_TUPLE

    _TESTS = [{
        'url': 'https://gns3.teachable.com/courses/gns3-certified-associate/lectures/6842364',
        'info_dict': {
            'id': 'untlgzk1v7',

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Read the alert text in the message — it is the school's own login failure reason; correct the credentials in .netrc or --username/--password accordingly.
  2. Confirm the login works in a browser on the same site; if the browser also fails, fix the account first.
  3. Verify you are using credentials for the right school subdomain (Teachable accounts are per-site in this extractor).
  4. If MFA is required, create a session in a browser and reuse cookies rather than CLI login.
Defensive patterns

Strategy: validation

Validate before calling

# Verify credentials in a browser first; programmatic equivalent is just
# attempting login and inspecting the expected alert error

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if e.expected and 'Unable to login' in str(e):
        log.error('Teachable login refused: %s', str(e))  # alert text included
        notify_credentials_issue(site)
    else:
        raise

Prevention

When it happens

Trigger: Logging in with wrong username/password or a locked/disabled account on any Teachable-based site: the school returns its HTML page with an alert div instead of a logged-in session.

Common situations: Wrong or stale password (school reset it); expired/deleted course accounts; password managers auto-filling outdated netrc entries; MFA-enabled accounts that cannot complete the CLI flow.

Related errors


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