ytdl-org/youtube-dl · error · ExtractorError

Unable to login: %s

Error message

Unable to login: %s

What it means

Raised by TumblrIE login when the post-login redirect did not land on /dashboard AND the response contains a RegistrationForm.errors JS array. The first error string is surfaced with the 'Unable to login:' prefix; expected=True. It means Tumblr rejected the credentials (or the legacy form flow).

Source

Thrown at youtube_dl/extractor/tumblr.py:140

        response, urlh = self._download_webpage_handle(
            self._LOGIN_URL, None, 'Logging in',
            data=urlencode_postdata(login_form), headers={
                'Content-Type': 'application/x-www-form-urlencoded',
                'Referer': self._LOGIN_URL,
            })

        # Successful login
        if '/dashboard' in urlh.geturl():
            return

        login_errors = self._parse_json(
            self._search_regex(
                r'RegistrationForm\.errors\s*=\s*(\[.+?\])\s*;', response,
                'login errors', default='[]'),
            None, fatal=False)
        if login_errors:
            raise ExtractorError(
                'Unable to login: %s' % login_errors[0], expected=True)

        self.report_warning('Login has probably failed')

    def _real_extract(self, url):
        m_url = re.match(self._VALID_URL, url)
        video_id = m_url.group('id')
        blog = m_url.group('blog_name')

        url = 'http://%s.tumblr.com/post/%s/' % (blog, video_id)
        webpage, urlh = self._download_webpage_handle(url, video_id)

        redirect_url = urlh.geturl()
        if 'tumblr.com/safe-mode' in redirect_url or redirect_url.startswith('/safe-mode'):
            raise ExtractorError(
                'This Tumblr may contain sensitive media. '
                'Disable safe mode in your account settings '
                'at https://www.tumblr.com/settings/account#safe_mode',

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Confirm the credentials work in a browser (also check for 2FA)
  2. Use cookies instead: log in with a browser and pass --cookies-from-browser/--cookies to yt-dlp
  3. Update to yt-dlp; its TumblrIE uses cookies only
  4. For scripts, catch expected ExtractorError from _login and fall back to anonymous extraction where content allows

Example fix

# before
yt-dl --username USER --password PASS 'http://blog.tumblr.com/post/123'
# after
yt-dlp --cookies-from-browser firefox 'http://blog.tumblr.com/post/123'
Defensive patterns

Strategy: fallback

Try / catch

try:
    ydl.download([url])
except ExtractorError as e:
    if e.expected and 'Unable to login' in str(e):
        run(['yt-dlp', '--cookies', 'tumblr.txt', url])  # cookie fallback

Prevention

When it happens

Trigger: Passing --username/--password to the Tumblr extractor: after submitting the login form, the page embeds RegistrationForm.errors = ["..."], typically 'Invalid username or password' or a captcha/challenge requirement.

Common situations: Wrong credentials; Tumblr adding two-factor auth or captcha on old form logins; automated logins flagged. Modern yt-dlp removed Tumblr password login in favor of cookies.

Related errors


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