{"record":{"id":"befc86fb9b084eac","repo":"ytdl-org/youtube-dl","slug":"redirect-failed","errorCode":null,"errorMessage":"Redirect failed","messagePattern":"Redirect failed","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/hotnewhiphop.py","lineNumber":57,"sourceCode":"            ('mediaId', video_id),\n        ])\n        r = sanitized_Request(\n            'http://www.hotnewhiphop.com/ajax/media/getActions/', data=reqdata)\n        r.add_header('Content-Type', 'application/x-www-form-urlencoded')\n        mkd = self._download_json(\n            r, video_id, note='Requesting media key',\n            errnote='Could not download media key')\n        if 'mediaKey' not in mkd:\n            raise ExtractorError('Did not get a media key')\n\n        redirect_url = compat_b64decode(video_url_base64).decode('utf-8')\n        redirect_req = HEADRequest(redirect_url)\n        req = self._request_webpage(\n            redirect_req, video_id,\n            note='Resolving final URL', errnote='Could not resolve final URL')\n        video_url = req.geturl()\n        if video_url.endswith('.html'):\n            raise ExtractorError('Redirect failed')\n\n        video_title = self._og_search_title(webpage).strip()\n\n        return {\n            'id': video_id,\n            'url': video_url,\n            'title': video_title,\n            'thumbnail': self._og_search_thumbnail(webpage),\n        }\n","sourceCodeStart":39,"sourceCodeEnd":67,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/hotnewhiphop.py#L39-L67","documentation":"Raised by the HotNewHipHop extractor after resolving the base64-decoded redirect URL via a HEAD request: the final URL still ends in .html, meaning the CDN bounced the request back to a player/error page instead of the media file.","triggerScenarios":"The HEAD redirect from the resolved media URL lands on an .html page — typically the site's generic player or an error page because the media link expired, is geo-fenced, or requires the session that the browser had.","commonSituations":"Expired signed media URLs, hotlink protection keyed to browser cookies/referer, or HNHH infra changes after one of the site's redesigns.","solutions":["Retry with a fresh page fetch so the base64 media URL is newly generated","Update youtube-dl/yt-dlp for current HNHH infrastructure","Grab the real media URL from devtools (Network tab, filter by media) and download directly","Check whether the track plays in a browser at all"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import requests\nfinal = requests.head(redirect_url, allow_redirects=True).url\nif final.endswith('.html'):\n    print('Redirect bounced to an HTML page — media link dead or hotlink-protected')","typeGuard":"def redirect_is_media(final_url):\n    return not final_url.lower().endswith(('.html', '.htm'))","tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept DownloadError as e:\n    if 'Redirect failed' in str(e):\n        refetch_fresh_page_and_retry(url)  # base64 media URL likely expired\n    else:\n        raise","preventionTips":["Always re-fetch the HNHH page immediately before extraction so the base64 URL is fresh","Extract the real media URL from devtools as a fallback","Treat .html redirects as expired/protected links, not network errors"],"tags":["hotnewhiphop","redirect","hotlink-protection","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}