{"record":{"id":"fd8328103868c0b4","repo":"ytdl-org/youtube-dl","slug":"unable-to-login-s-fd8328","errorCode":null,"errorMessage":"Unable to login: %s","messagePattern":"Unable to login: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/tumblr.py","lineNumber":140,"sourceCode":"\n        response, urlh = self._download_webpage_handle(\n            self._LOGIN_URL, None, 'Logging in',\n            data=urlencode_postdata(login_form), headers={\n                'Content-Type': 'application/x-www-form-urlencoded',\n                'Referer': self._LOGIN_URL,\n            })\n\n        # Successful login\n        if '/dashboard' in urlh.geturl():\n            return\n\n        login_errors = self._parse_json(\n            self._search_regex(\n                r'RegistrationForm\\.errors\\s*=\\s*(\\[.+?\\])\\s*;', response,\n                'login errors', default='[]'),\n            None, fatal=False)\n        if login_errors:\n            raise ExtractorError(\n                'Unable to login: %s' % login_errors[0], expected=True)\n\n        self.report_warning('Login has probably failed')\n\n    def _real_extract(self, url):\n        m_url = re.match(self._VALID_URL, url)\n        video_id = m_url.group('id')\n        blog = m_url.group('blog_name')\n\n        url = 'http://%s.tumblr.com/post/%s/' % (blog, video_id)\n        webpage, urlh = self._download_webpage_handle(url, video_id)\n\n        redirect_url = urlh.geturl()\n        if 'tumblr.com/safe-mode' in redirect_url or redirect_url.startswith('/safe-mode'):\n            raise ExtractorError(\n                'This Tumblr may contain sensitive media. '\n                'Disable safe mode in your account settings '\n                'at https://www.tumblr.com/settings/account#safe_mode',","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/tumblr.py#L122-L158","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the credentials work in a browser (also check for 2FA)","Use cookies instead: log in with a browser and pass --cookies-from-browser/--cookies to yt-dlp","Update to yt-dlp; its TumblrIE uses cookies only","For scripts, catch expected ExtractorError from _login and fall back to anonymous extraction where content allows"],"exampleFix":"# before\nyt-dl --username USER --password PASS 'http://blog.tumblr.com/post/123'\n# after\nyt-dlp --cookies-from-browser firefox 'http://blog.tumblr.com/post/123'","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.download([url])\nexcept ExtractorError as e:\n    if e.expected and 'Unable to login' in str(e):\n        run(['yt-dlp', '--cookies', 'tumblr.txt', url])  # cookie fallback","preventionTips":["Prefer cookie-based auth; Tumblr's form login is legacy","Check for 2FA/captcha when browser login also struggles","Many Tumblr posts extract anonymously — only pass credentials when required"],"tags":["extractor","auth","login","tumblr","expected"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}