{"record":{"id":"88bb3b14ef89bbf2","repo":"ytdl-org/youtube-dl","slug":"unable-to-login-s-88bb3b","errorCode":null,"errorMessage":"Unable to login: %s","messagePattern":"Unable to login: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/pornhub.py","lineNumber":115,"sourceCode":"        })\n\n        response = self._download_json(\n            'https://www.%s/front/authenticate' % host, None,\n            'Logging in to %s' % site,\n            data=urlencode_postdata(login_form),\n            headers={\n                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n                'Referer': login_url,\n                'X-Requested-With': 'XMLHttpRequest',\n            })\n\n        if response.get('success') == '1':\n            self._logged_in = True\n            return\n\n        message = response.get('message')\n        if message is not None:\n            raise ExtractorError(\n                'Unable to login: %s' % message, expected=True)\n\n        raise ExtractorError('Unable to log in')\n\n\nclass PornHubIE(PornHubBaseIE):\n    IE_DESC = 'PornHub and Thumbzilla'\n    _VALID_URL = r'''(?x)\n                    https?://\n                        (?:\n                            (?:[^/]+\\.)?\n                            %s\n                            /(?:(?:view_video\\.php|video/show)\\?viewkey=|embed/)|\n                            (?:www\\.)?thumbzilla\\.com/video/\n                        )\n                        (?P<id>[\\da-z]+)\n                    ''' % PornHubBaseIE._PORNHUB_HOST_RE\n    _TESTS = [{","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/pornhub.py#L97-L133","documentation":"PornHubBaseIE._login raises ExtractorError('Unable to login: %s' % message, expected=True) when the AJAX POST to the login endpoint returns JSON with success != '1' but includes a 'message' field. The interpolated text is the site's own failure reason (e.g. wrong username/password or CAPTCHA required). Expected=True makes it a reportable credential problem rather than an extractor crash.","triggerScenarios":"Running with --username/--password where the credentials are wrong or the account requires a CAPTCHA; the POST to login_url with X-Requested-With/Referer headers returns {'success': '0', 'message': '...'}; partial two-factor or locked accounts also return here.","commonSituations":"Typo'd or expired passwords; PornHub intermittently requiring reCAPTCHA on API logins (which the extractor cannot solve); account locked/flagged; password managers inserting stale credentials; too many login attempts triggering anti-bot.","solutions":["Verify the username/password pair logs in successfully in a normal browser session.","If the message indicates a CAPTCHA, log in manually once in a browser and pass cookies (--cookies from a cookies.txt) instead of username/password.","Check the exact site message in the error text — it names the real failure (bad credentials, locked account, etc.).","Update youtube-dl, as login endpoint/parameter changes are fixed in newer releases."],"exampleFix":"# before\nyoutube_dl --username me --password 'typo' URL\n\n# after\n# export browser cookies and skip password login\nyoutube_dl --cookies cookies.txt URL","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if str(e).startswith('Unable to login:'):\n        # fall back to cookie-based auth\n        ...","preventionTips":["Prefer --cookies from a real browser session over username/password for this site.","Never hard-code credentials; read them from a secret store and verify in a browser first.","Watch the message text — it names the actual cause (bad password vs CAPTCHA)."],"tags":["pornhub","authentication","credentials","captcha"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}