Skip to content

[Twitch] Regression: Failed to download m3u8 information: HTTP Error 403: Forbidden #13581

@physanus

Description

@physanus

Checklist

  • I'm reporting that yt-dlp is broken on a supported site
  • I've verified that I have updated yt-dlp to nightly or master (update instructions)
  • I've checked that all provided URLs are playable in a browser with the same IP and same login details
  • I've checked that all URLs and arguments with special characters are properly quoted or escaped
  • I've searched known issues, the FAQ, and the bugtracker for similar issues including closed ones. DO NOT post duplicates
  • I've read about sharing account credentials and I'm willing to share it if required

Region

No response

Provide a description that is worded well enough to be understood

Commit 7b81634 introduced a regression that prevents the download of protected Twitch VODs restricted to subscribers.

Steps to reproduce:

  1. Install yt-dlp
  2. Install the "requests" package via pip install requests
  3. Save your cookies to a file, e.g. /tmp/cookies.txt
  4. Attempt to download a subscribers-only VOD, such as this one

After downgrading to commit 7e2504f, the download works as expected, with no other changes made. This is also the case when uninstalling the "requests" package.

Provide verbose output that clearly demonstrates the problem

  • Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
  • If using API, add 'verbose': True to YoutubeDL params instead
  • Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output

$ yt-dlp -vU --cookies /tmp/cookies.txt https://www.twitch.tv/videos/2496519050
[debug] Command-line config: ['-vU', '--cookies', '/tmp/cookies.txt', 'https://www.twitch.tv/videos/2496519050']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2025.06.25 from yt-dlp/yt-dlp [1838a1ce5]
[debug] Lazy loading extractors is disabled
[debug] Python 3.13.0 (CPython x86_64 64bit) - Linux-6.8.0-62-generic-x86_64-with (OpenSSL 3.3.2 3 Sep 2024)
[debug] exe versions: ffmpeg 6.1.1 (setts), ffprobe 6.1.1
[debug] Optional libraries: certifi-2025.06.15, mutagen-1.47.0, requests-2.32.4, sqlite3-3.45.3, urllib3-2.5.0
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests
[debug] Plugin directories: none
[debug] Loaded 1856 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
Latest version: stable@2025.06.25 from yt-dlp/yt-dlp
yt-dlp is up to date (stable@2025.06.25 from yt-dlp/yt-dlp)
[twitch:vod] Extracting URL: https://www.twitch.tv/videos/2496519050
[twitch:vod] 2496519050: Downloading stream metadata GraphQL
[twitch:vod] 2496519050: Downloading video access token GraphQL
[twitch:vod] 2496519050: Downloading m3u8 information
ERROR: [twitch:vod] 2496519050: Failed to download m3u8 information: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/common.py", line 753, in extract
    ie_result = self._real_extract(url)
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/twitch.py", line 555, in _real_extract
    formats = self._extract_twitch_m3u8_formats(
        'vod', vod_id, access_token['value'], access_token['signature'],
        live_from_start=self.get_param('live_from_start'))
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/twitch.py", line 191, in _extract_twitch_m3u8_formats
    formats = self._extract_m3u8_formats(
        f'{self._USHER_BASE}/{path}/{video_id}.m3u8', video_id, 'mp4', query={
    ...<9 lines>...
            'token': token,
        })
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/common.py", line 2112, in _extract_m3u8_formats
    fmts, subs = self._extract_m3u8_formats_and_subtitles(*args, **kwargs)
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/common.py", line 2137, in _extract_m3u8_formats_and_subtitles
    response = self._request_webpage(
        m3u8_url, video_id, note=note, errnote=errnote,
        fatal=fatal, data=data, headers=headers, query=query)
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/common.py", line 922, in _request_webpage
    raise ExtractorError(errmsg, cause=err)

  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/extractor/common.py", line 909, in _request_webpage
    return self._downloader.urlopen(self._create_request(url_or_request, data, headers, query, extensions))
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/YoutubeDL.py", line 4197, in urlopen
    return self._request_director.send(req)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/networking/common.py", line 117, in send
    response = handler.send(request)
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/networking/_helper.py", line 194, in wrapper
    return func(self, *args, **kwargs)
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/networking/common.py", line 359, in send
    return self._send(request)
           ~~~~~~~~~~^^^^^^^^^
  File "/home/default/.local/lib/python3.13/site-packages/yt_dlp/networking/_requests.py", line 368, in _send
    raise HTTPError(res, redirect_loop=max_redirects_exceeded)
yt_dlp.networking.exceptions.HTTPError: HTTP Error 403: Forbidden

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug that is not site-specifichigh-priorityregressionWorks in youtube-dl/older yt-dlpsite-bugIssue with a specific website

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions