--- title: "yt-dlp YouTube JS Challenge Fix (Fedora)" domain: troubleshooting category: general tags: [yt-dlp, fedora, youtube, javascript, deno] status: published created: 2026-04-02 updated: 2026-04-02 --- # 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: ```bash 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 ```bash 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: ```bash 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: ```bash mkdir -p ~/.config/yt-dlp echo '--remote-components ejs:github' > ~/.config/yt-dlp/config ``` --- ## Maintenance YouTube pushes extractor changes frequently. Keep yt-dlp current: ```bash 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: ```bash 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: ```bash yt-dlp --list-formats --remote-components ejs:github \ https://www.youtube.com/watch?v=VIDEO_ID ``` ### HTTP 429 Too Many Requests + Impersonation Warning Downloads or subtitle fetches fail with: ``` WARNING: The extractor specified to use impersonation for this download, but no impersonate target is available. ERROR: Unable to download video subtitles for 'en-en-US': HTTP Error 429: Too Many Requests ``` **Cause:** yt-dlp needs `curl_cffi` to impersonate a real browser's TLS fingerprint. Without it, YouTube detects the non-browser client and rate-limits with 429s. Subtitle downloads are usually the first to fail. **Fix:** ```bash pip3 install --upgrade yt-dlp curl_cffi ``` Once `curl_cffi` is installed, yt-dlp automatically uses browser impersonation and the 429s stop. No config changes needed. ### 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: ```bash 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:** ```bash 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):** ```bash 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:** ```bash yt-dlp --list-formats https://youtu.be/VIDEO_ID ```