ytdl-org/youtube-dl · error · ExtractorError

Unable to login. Twitch said: %s

Error message

Unable to login. Twitch said: %s

What it means

Raised by TwitchTvIE._login (via the local fail() helper) when a step of the interactive login flow reports an error — e.g. wrong credentials, CAPTCHA/verification wall, or 'blocked' message parsed from the login pages. Expected error: the message after 'Twitch said:' comes from Twitch's response, not youtube-dl.

Source

Thrown at youtube_dl/extractor/twitch.py:66

        'ClipsCards__User': 'b73ad2bfaecfd30a9e6c28fada15bd97032c83ec77a0440766a56fe0bd632777',
        'ChannelCollectionsContent': '07e3691a1bad77a36aba590c351180439a40baefc1c275356f40fc7082419a84',
        'StreamMetadata': '1c719a40e481453e5c48d9bb585d971b8b372f8ebb105b17076722264dfa5b3e',
        'ComscoreStreamingQuery': 'e1edae8122517d013405f237ffcc124515dc6ded82480a88daef69c83b53ac01',
        'VideoAccessToken_Clip': '36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11',
        'VideoPreviewOverlay': '3006e77e51b128d838fa4e835723ca4dc9a05c5efd4466c1085215c6e437e65c',
        'VideoMetadata': '226edb3e692509f727fd56821f5653c05740242c82b0388883e0c0e75dcbf687',
    }

    def _real_initialize(self):
        self._login()

    def _login(self):
        username, password = self._get_login_info()
        if username is None:
            return

        def fail(message):
            raise ExtractorError(
                'Unable to login. Twitch said: %s' % message, expected=True)

        def login_step(page, urlh, note, data):
            form = self._hidden_inputs(page)
            form.update(data)

            page_url = urlh.geturl()
            post_url = self._search_regex(
                r'<form[^>]+action=(["\'])(?P<url>.+?)\1', page,
                'post url', default=self._LOGIN_POST_URL, group='url')
            post_url = urljoin(page_url, post_url)

            headers = {
                'Referer': page_url,
                'Origin': 'https://www.twitch.tv',
                'Content-Type': 'text/plain;charset=UTF-8',
            }

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Use cookie-based auth instead: log in with a browser, export cookies, and pass --cookies twitch_cookies.txt.
  2. Verify credentials work in a browser; reset password if not.
  3. Supply --twofactor <code> if the account has 2FA.
  4. Update to yt-dlp, where Twitch login handling was reworked (and cookie auth is the recommended path).
Defensive patterns

Strategy: fallback

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if 'Unable to login' in str(e):
        switch_to_cookie_auth()  # re-run with --cookies from browser session
    else:
        raise

Prevention

When it happens

Trigger: Running with --username/--password so _get_login_info() returns credentials, then a login_step POST returns a page containing an error/authy/captcha/blocked marker, triggering fail(message). Twitch may also step up with 2FA prompts that youtube-dl cannot answer.

Common situations: Incorrect or expired password, Twitch forcing CAPTCHA or device verification on automated logins, 2FA-enabled accounts, using --twofactor incorrectly.

Related errors


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