Files
MajorWiki/05-troubleshooting/yt-dlp-fedora-js-challenge.md
MajorLinux 6da77c2db7 wiki: remove Obsidian-style hashtag tags from 12 articles
These #hashtag tag lines render as plain text on MkDocs. All articles
already have tags in YAML frontmatter, so the inline tags were redundant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:03:28 -04:00

5.1 KiB

yt-dlp YouTube JS Challenge Fix (Fedora)

Problem

When running yt-dlp on Fedora, downloads may fail with the following warnings and errors:

WARNING: [youtube] No supported JavaScript runtime could be found.
WARNING: [youtube] [jsc:deno] Challenge solver lib script version 0.3.2 is not supported (supported version: 0.4.0)
WARNING: [youtube] 0qhgPKRzlvs: n challenge solving failed: Some formats may be missing.
ERROR: Did not get any data blocks
ERROR: fragment 1 not found, unable to continue

This causes subtitle downloads (and sometimes video formats) to fail silently, with the MP4 completing but subtitles being skipped.

Root Causes

  1. No JavaScript runtime installed — yt-dlp requires Deno or Node.js to solve YouTube's JS challenges
  2. Outdated yt-dlp — the bundled challenge solver script is behind the required version
  3. Remote challenge solver not enabled — the updated solver script must be explicitly fetched

Fix

1. Install Deno

Deno is not in the Fedora repos. Install via the official installer:

curl -fsSL https://deno.land/install.sh | sh
sudo mv ~/.deno/bin/deno /usr/local/bin/deno
deno --version

Alternatively, Node.js works and is available via sudo dnf install nodejs.

2. Update yt-dlp

sudo pip install -U yt-dlp --break-system-packages

If installed via standalone binary: yt-dlp -U

3. Enable Remote Challenge Solver

Add --remote-components ejs:github to the yt-dlp command. This fetches the latest JS challenge solver from GitHub at runtime:

yt-dlp -f 'bestvideo[vcodec^=avc]+bestaudio[ext=m4a]/bestvideo+bestaudio' \
  --merge-output-format mp4 \
  -o "/plex/plex/%(title)s.%(ext)s" \
  --write-auto-subs --embed-subs \
  --remote-components ejs:github \
  https://www.youtube.com/watch?v=VIDEO_ID

4. Persist the Config

Create a yt-dlp config file so --remote-components is applied automatically:

mkdir -p ~/.config/yt-dlp
echo '--remote-components ejs:github' > ~/.config/yt-dlp/config

Maintenance

YouTube pushes extractor changes frequently. Keep yt-dlp current:

sudo pip install -U yt-dlp --break-system-packages

Known Limitations

n-Challenge Failure: "found 0 n function possibilities"

Even with Deno installed, the remote solver downloaded, and yt-dlp up to date, some YouTube player versions can still fail n-challenge solving:

WARNING: [youtube] [jsc] Error solving n challenge request using "deno" provider:
Error running deno process (returncode: 1): error: Uncaught (in promise)
"found 0 n function possibilities".
WARNING: [youtube] n challenge solving failed: Some formats may be missing.
ERROR: [youtube] Requested format is not available.

This is a known upstream issue tied to specific YouTube player builds (e.g. e42f4bf8). It is not fixable locally — it requires a yt-dlp patch when YouTube rotates the player.

Workaround: Use a permissive format fallback instead of forcing AVC:

yt-dlp -f 'bestvideo+bestaudio/best' \
  --merge-output-format mp4 \
  -o "/plex/plex/%(title)s.%(ext)s" \
  --write-auto-subs --embed-subs \
  --remote-components ejs:github \
  https://www.youtube.com/watch?v=VIDEO_ID

This lets yt-dlp pick the best available format rather than failing on a missing AVC stream. To inspect what formats are actually available:

yt-dlp --list-formats --remote-components ejs:github \
  https://www.youtube.com/watch?v=VIDEO_ID

SABR-Only Streaming Warning

Some videos may show:

WARNING: [youtube] Some android_vr client https formats have been skipped as they
are missing a URL. YouTube may have enabled the SABR-only streaming experiment.

This is a YouTube-side experiment. yt-dlp falls back to other clients automatically — no action needed.

pip Version Check

pip show does not accept --break-system-packages. Run separately:

yt-dlp --version
pip show yt-dlp

Format Not Available: Strict AVC+M4A Selector

The format selector bestvideo[vcodec^=avc]+bestaudio[ext=m4a] will hard-fail if YouTube doesn't serve H.264 (AVC) video for a given video:

ERROR: [youtube] Requested format is not available. Use --list-formats for a list of available formats

This is separate from the n-challenge issue — the format simply doesn't exist for that video (common with newer uploads that are VP9/AV1-only).

Fix 1 — Relax the selector to mp4 container without enforcing codec:

yt-dlp -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio' \
  --merge-output-format mp4 \
  -o "/plex/plex/%(title)s.%(ext)s" \
  --write-auto-subs --embed-subs \
  https://youtu.be/VIDEO_ID

Fix 2 — Let yt-dlp pick best and re-encode to H.264 via ffmpeg (Plex-safe, slower):

yt-dlp -f 'bestvideo+bestaudio' \
  --merge-output-format mp4 \
  --recode-video mp4 \
  -o "/plex/plex/%(title)s.%(ext)s" \
  --write-auto-subs --embed-subs \
  https://youtu.be/VIDEO_ID

Use --recode-video mp4 when Plex direct play is required and the source stream may be VP9/AV1. Requires ffmpeg.

Inspect available formats first:

yt-dlp --list-formats https://youtu.be/VIDEO_ID