Skip to content

iwara.tv extractors broken due to Cloudflare #13672

@Strad

Description

@Strad

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

United States

Provide a description that is worded well enough to be understood

Summary

Since July 8, 2025, Iwara has implemented Cloudflare protection (likely Turnstile or Managed Challenge), which breaks yt-dlp’s ability to fetch metadata and download videos. This results in a JSONDecodeError, as Cloudflare returns HTML instead of JSON when the API endpoint is hit without a valid session.


Error output

[iwara] 7rr1s5u30B2RtG: Downloading JSON metadata
ERROR: [iwara] 7rr1s5u30B2RtG: 7rr1s5u30B2RtG: Failed to parse JSON (caused by JSONDecodeError("Expecting value in '': line 1 column 1 (char 0)"))

Analysis

  • Iwara now uses Cloudflare's managed JS challenges, which the current extractor cannot bypass.
  • The site no longer provides a traditional login cookie (connect.sid, laravel_session, etc.).
  • Instead, login state is stored in localStorage in the form of a Bearer token.
  • This token is used for all authenticated API calls via: Authorization: Bearer <token>
  • Neither --username/--password nor --cookies can be used to bypass the new system.
  • cf_clearance alone is insufficient.

Example video (NSFW) https://www.iwara.tv/video/7rr1s5u30B2RtG/darkside-or-marvel-rivals-hmv

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

(P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda) PS M:\Vids> yt-dlp --verbose https://www.iwara.tv/video/7rr1s5u30B2RtG/darkside-or-marvel-rivals-hmv
[debug] Command-line config: ['--verbose', 'https://www.iwara.tv/video/7rr1s5u30B2RtG/darkside-or-marvel-rivals-hmv']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2025.06.30 from yt-dlp/yt-dlp [b01878449] (pip)
[debug] Python 3.12.7 (CPython AMD64 64bit) - Windows-11-10.0.26100-SP0 (OpenSSL 3.0.15 3 Sep 2024)
[debug] exe versions: ffmpeg 4.3.1, ffprobe 4.3.1
[debug] Optional libraries: certifi-2024.08.30, requests-2.32.3, sqlite3-3.45.3, urllib3-2.2.3
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests
[debug] Extractor Plugins: PMVHavenVideoIE
[debug] Post-Processor Plugins: StashPP
[debug] Plugin directories: P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp_plugins
[debug] Loaded 1865 extractors
[iwara] Extracting URL: https://www.iwara.tv/video/7rr1s5u30B2RtG/darkside-or-marvel-rivals-hmv
[iwara] 7rr1s5u30B2RtG: Downloading JSON metadata
ERROR: [iwara] 7rr1s5u30B2RtG: 7rr1s5u30B2RtG: Failed to parse JSON (caused by JSONDecodeError("Expecting value in '': line 1 column 1 (char 0)")); please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 752, in extract
    ie_result = self._real_extract(url)
                ^^^^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\iwara.py", line 167, in _real_extract
    video_data = self._download_json(
                 ^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1149, in download_content
    res = getattr(self, download_handle.__name__)(url_or_request, video_id, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1114, in download_handle
    return parse(self, content, video_id, transform_source=transform_source, fatal=fatal, errnote=errnote), urlh
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1102, in parse
    return getattr(ie, parser)(content, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1089, in _parse_json
    self.__print_error('Failed to parse JSON' if errnote is None else errnote, fatal, video_id, ve)
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1072, in __print_error
    raise ExtractorError(f'{video_id}: {errnote}', cause=err)

  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\utils\_utils.py", line 567, in decode
    return super().decode(s)
           ^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\extractor\common.py", line 1086, in _parse_json
    return json.loads(
           ^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\json\__init__.py", line 359, in loads
    return cls(**kw).decode(s)
           ^^^^^^^^^^^^^^^^^^^
  File "P:\Assets\Scripting\yt-dlp-stash\yt-dlp-stash\.conda\Lib\site-packages\yt_dlp\utils\_utils.py", line 575, in decode
    raise type(e)(f'{e.msg} in {s[e.pos - 10:e.pos + 10]!r}', s, e.pos)
json.decoder.JSONDecodeError: Expecting value in '': line 1 column 1 (char 0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    NSFWsite-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