Sign in to confirm you’re not a bot: why yt-dlp gets blocked
YouTube asks some sessions to sign in before it serves a video. What the yt-dlp error means, the documented request limits.
ERROR: [youtube] VIDEO_ID: Sign in to confirm you’re not a bot. Use --cookies-from-browser or --cookies for the authentication. Short answer
YouTube asks some sessions to sign in before it serves a video. What the yt-dlp error means, the documented request limits, and what the maintainers say helps and what does not.
Diagnosis checked 2026-11-11; sources below.Why it happens
YouTube refused to play the video for this session and asked for a signed-in account; yt-dlp passes the message on. Its maintainers point to downloading too much too fast and to data-center IPs, which are more likely to be blocked. Source: yt-dlp issue #10128.
Do this now
- If the data is yours or your use fits the official terms, switch to the official route: YouTube Data API v3 (Public API). No per-call fee is published; the constraint is the daily quota. Extra quota is not self-serve.
- For video files and metadata at volume, run a hosted route instead of patching your own requests: YouTube Video, Playlist & Channel Downloader with Metadata. The request below runs it with its published example input through the Apify API (your token, billed at the Store price).
- Compare every route, with fields and prices, on the YouTube page.
Python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"mode": "metadata",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
],
"playlistUrls": [],
"channelUrls": [],
"searchQueries": [],
"videoQuality": "360p",
"container": "auto",
"audioOnly": False,
"audioFormat": "m4a",
"downloadSubtitles": False,
"subtitleLanguages": [
"en"
],
"subtitleFormat": "vtt",
"includeTranscript": False,
"maxVideos": 1,
"maxMinutes": 30,
"maxMB": 100,
"allow4K": False,
"storage": "ephemeral_kvs",
"storageRetentionDays": 7,
"s3Prefix": "youtube-downloader",
"s3Region": "auto",
"proxyConfiguration": {
"useApifyProxy": True
}
}
run = client.actor("nimbryxo-studio/youtube-video-playlist-and-channel-downloader").call(run_input=run_input)
if run is None:
raise RuntimeError("The Actor run was not found.")
for item in client.dataset(run.default_dataset_id).iterate_items():
print(item) pip install apify-client
JavaScript
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });
const input = {
"mode": "metadata",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
],
"playlistUrls": [],
"channelUrls": [],
"searchQueries": [],
"videoQuality": "360p",
"container": "auto",
"audioOnly": false,
"audioFormat": "m4a",
"downloadSubtitles": false,
"subtitleLanguages": [
"en"
],
"subtitleFormat": "vtt",
"includeTranscript": false,
"maxVideos": 1,
"maxMinutes": 30,
"maxMB": 100,
"allow4K": false,
"storage": "ephemeral_kvs",
"storageRetentionDays": 7,
"s3Prefix": "youtube-downloader",
"s3Region": "auto",
"proxyConfiguration": {
"useApifyProxy": true
}
};
const run = await client.actor("nimbryxo-studio/youtube-video-playlist-and-channel-downloader").call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items); npm install apify-client
cURL
curl -X POST "https://api.apify.com/v2/actors/nimbryxo-studio~youtube-video-playlist-and-channel-downloader/run-sync-get-dataset-items" -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" -d '{"mode":"metadata","videoUrls":["https://www.youtube.com/watch?v=jNQXAC9IVRw"],"playlistUrls":[],"channelUrls":[],"searchQueries":[],"videoQuality":"360p","container":"auto","audioOnly":false,"audioFormat":"m4a","downloadSubtitles":false,"subtitleLanguages":["en"],"subtitleFormat":"vtt","includeTranscript":false,"maxVideos":1,"maxMinutes":30,"maxMB":100,"allow4K":false,"storage":"ephemeral_kvs","storageRetentionDays":7,"s3Prefix":"youtube-downloader","s3Region":"auto","proxyConfiguration":{"useApifyProxy":true}}' Waits for the run and returns the dataset items (runs over 300 seconds return HTTP 408; start an async run instead).
MCP (AI agents)
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=nimbryxo-studio/youtube-video-playlist-and-channel-downloader",
"headers": {
"Authorization": "Bearer <YOUR_APIFY_TOKEN>"
}
}
}
} Adds this Actor as a tool in an MCP client that takes a remote server URL (Cursor, VS Code, Claude Code) through Apify's hosted MCP server. OAuth sign-in also works without the header. Clients that only start local servers can wrap the URL with npx mcp-remote.
Open YouTube Video, Playlist & Channel Downloader with Metadata in Apify Store
Routes that work for YouTube data
The official route first, then the catalogue Actors that fit this problem (video files and metadata), by their published fields. Store figures are the publisher's public numbers.
| Route | Core fields | Price / 1K | Success, 30 days | Link |
|---|---|---|---|---|
| Public APIYouTube Data API v3 | not compared | below | Official docs | |
| YouTube Video, Playlist & Channel Downloader with Metadata | 4/8 | $0.99 | 96% of 24 runs | Open in Apify Store |
| YouTube Video Metadata & Chapter Extractor | 7/8 | $0.99 | 16 runs, too few to rate | Open in Apify Store |
| YouTube Caption & Whisper AI Transcript Extractor | 6/8 | $0.99 | 92% of 26 runs | Open in Apify Store |
Official price: No per-call fee is published; the constraint is the daily quota. Extra quota is not self-serve. Compare all 25 YouTube routes.
The facts behind the error
| Fact | Value |
|---|---|
| What it means | YouTube refused to play the video for this session and asked for a signed-in account; yt-dlp passes the message on and adds a cookies hint |
| Documented cause | yt-dlp maintainers point to downloading too much too fast and to data-center IPs, which are more likely to be blocked |
| Documented request limits | About 300 videos an hour for guest sessions and about 2,000 an hour for accounts; the wiki suggests a 5-10 second delay between downloads |
| PO Token support | The po_token extractor argument shipped in yt-dlp 2024.09.27 (pull request #10648) |
| JavaScript runtime | Since yt-dlp 2025.11.12 an external JavaScript runtime (Deno recommended) is required for full YouTube support |
| Account risk | The yt-dlp wiki warns that an account used with yt-dlp can be banned, temporarily or permanently |
| Tracking issue | Issue #10128 opened June 7, 2024 and was closed November 21, 2024 as outside yt-dlp's control |
Website pages
Sources
Every dated claim on this page comes from the public sources below. Check the source before you make a business decision on it.
- yt-dlp issue #10128 — checked 2026-11-11
- yt-dlp wiki: Extractors (YouTube) — checked 2026-11-11
- yt-dlp release 2024.09.27 — checked 2026-11-11
- yt-dlp issue #15012 (JavaScript runtime) — checked 2026-11-11
Get YouTube data with a catalogue Actor
YouTube Search Results & Entity Type Scraper returns 7 of 8 core YouTube fields at $0.99 per 1,000 results. Compare all 25 YouTube routes.