ytdl-org/youtube-dl · error · ExtractorError

Unable to login: %s

Error message

Unable to login: %s

What it means

Raised by the AnimeOnDemand login flow when the POST response lacks both '>Logout<' and 'href="/users/sign_out"' and an alert-styled <p> error was scraped from the page. The scraped alert text (German site messages like 'E-Mail oder Passwort falsch') is embedded into the message. Marked expected=True.

Source

Thrown at youtube_dl/extractor/animeondemand.py:92

        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 = urljoin(self._LOGIN_URL, post_url)

        response = self._download_webpage(
            post_url, None, 'Logging in',
            data=urlencode_postdata(login_form), headers={
                'Referer': self._LOGIN_URL,
            })

        if all(p not in response for p in ('>Logout<', 'href="/users/sign_out"')):
            error = self._search_regex(
                r'<p[^>]+\bclass=(["\'])(?:(?!\1).)*\balert\b(?:(?!\1).)*\1[^>]*>(?P<error>.+?)</p>',
                response, 'error', default=None, group='error')
            if error:
                raise ExtractorError('Unable to login: %s' % error, expected=True)
            raise ExtractorError('Unable to log in')

    def _real_initialize(self):
        self._login()

    def _real_extract(self, url):
        anime_id = self._match_id(url)

        webpage = self._download_webpage(url, anime_id)

        if 'data-playlist=' not in webpage:
            self._download_webpage(
                self._APPLY_HTML5_URL, anime_id,
                'Activating HTML5 beta', 'Unable to apply HTML5 beta')
            webpage = self._download_webpage(url, anime_id)

        csrf_token = self._html_search_meta(
            'csrf-token', webpage, 'csrf token', fatal=True)

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Verify credentials by logging in at anime-on-demand.de in a browser
  2. Confirm the subscription is active — locked accounts often produce alert errors on login POST
  3. If login works in the browser but not here, the alert markup likely changed; check upstream extractor updates
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if 'Unable to login' in str(e):
        # e.msg carries the German alert text; 'Unable to log in' (no colon) means markup changed
        prompt_relogin('animeondemand', detail=str(e))

Prevention

When it happens

Trigger: POST to the login form URL returns a page without logout markers; regex finds class containing 'alert' with inner text, e.g. wrong credentials or account restrictions; Devise/Rails login errors surfaced as alert paragraphs.

Common situations: Wrong --username/--password; account without an active Anime-on-Demand subscription; site markup change altering the alert class so only the generic 'Unable to log in' appears instead.

Related errors


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