The error#
1ERROR: [youtube] VIDEO_ID: Requested format is not available. Use --list-formats for a list of available formatsyt-dlp 2026.10.26 raises it in process_video_result (YoutubeDL.py) when the format selector returns an empty list. It is marked as expected, so there is no request to file a bug. From Python it arrives as yt_dlp.utils.DownloadError with the same text.
The selector is whatever you passed with -f, or the default when you passed nothing: bestvideo*+bestaudio/best, which becomes best/bestvideo+bestaudio (with a warning that ffmpeg was not found) when yt-dlp cannot merge two streams.
What causes it#
- The selector names something this video does not have. A fixed id such as
-f 137, an extension filter such as[ext=mp4]or a height that was never uploaded leaves nothing to pick, and with no/fallback the selection fails. - The list came back short. Formats are thrown away before selection when there is no JavaScript runtime to solve YouTube's challenges, when a client needs a PO token, or when YouTube serves a client by SABR only. Then even a sensible selector finds little or nothing.
- The video is new. A yt-dlp maintainer: "It's not unusual for the IOS m3u8 formats to take up to 24 hours to populate." Another added that it "usually happens for recently uploaded videos."
- You only wanted the captions.
--skip-downloaddoes not skip format selection. A subtitle job with a strict-fcan still fail here before a single caption is written.
How to tell which one it is#
List what yt-dlp actually found:
1yt-dlp -F "https://www.youtube.com/watch?v=VIDEO_ID"What -F shows | Cause |
|---|---|
A long list, but not the id or filter in your -f | 1 |
Only a handful of formats, or only sb storyboard images | 2: run with -v and read the warnings |
| Few formats on a video uploaded hours ago | 3 |
A full list, and your command has --skip-download | 4 |
For cause 2, the warnings name the reason: No supported JavaScript runtime could be found, require a GVS PO Token which was not provided, or formats have been skipped as they are missing a URL.
How to fix it#
1. Give the selector somewhere to fall back to. Each / is a second choice, and -S sorts by preference without ever failing on a missing id. A maintainer's own suggestion for one of these reports was to drop -f and sort instead.
1yt-dlp -f "bv*[height<=1080]+ba/b" "https://www.youtube.com/watch?v=VIDEO_ID"2yt-dlp -S "vcodec:h264,res,acodec:aac" "https://www.youtube.com/watch?v=VIDEO_ID"2. Do the same from Python. The option is format, and the error is a DownloadError you can catch per video.
1import yt_dlp23opts = {"format": "bestaudio/best", "quiet": True}4with yt_dlp.YoutubeDL(opts) as ydl:5 try:6 info = ydl.extract_info(url, download=True)7 except yt_dlp.utils.DownloadError as e:8 print("no format matched:", e)3. Fix the short list at its cause. Update yt-dlp, install Deno so the challenges can be solved, and read the PO token page if that warning is in the log.
4. Wait on a new upload, or prefer the formats that exist from the start: the same maintainer suggested -S proto:https.
5. Let a caption job carry on without formats. --ignore-no-formats-error turns this error into a warning, so the details and subtitles are still written.
1yt-dlp --skip-download --write-auto-subs --ignore-no-formats-error "https://www.youtube.com/watch?v=VIDEO_ID"If the format was only a step to the captions#
When the job is text, not media, there is no format to choose. GET /v1/youtube/video lists the caption tracks a video has, with language and whether YouTube generated them, and GET /v1/youtube/video/transcript returns one of them as text; pass language to pick it. A video with no captions answers transcript_unavailable and is not charged.
What SocialScrape cannot give you is the stream: it does not download YouTube video or audio, so a media pipeline still needs yt-dlp and the steps above. A transcript costs 1 credit, and you can try it with the 100 credits every new account gets.