Skip to content

yt-dlp: "Sign in to confirm you're not a bot" — what it means and how to fix it

By Tunelio teamPublished Updated

This error is YouTube’s bot wall, not a yt-dlp bug: YouTube decided your request looks automated and now wants a verified, signed-in session. Quick fix: update yt-dlp, install a JavaScript runtime (Deno), retry with IPv4. If that is not enough, the sections below walk through cookies, PO tokens and IP reputation in the order that actually works — with the mistakes that make it worse.

The 60-second fix (try this first)

Most reports we see are solved by three things: an outdated yt-dlp, a missing JavaScript runtime, or an IPv6 address that YouTube distrusts. Run these before touching cookies:

# 1. update (pip users: pip install -U yt-dlp)
yt-dlp -U

# 2. install a JS runtime for YouTube's challenge solving — Deno is the recommended one
curl -fsSL https://deno.land/install.sh | sh

# 3. retry over IPv4 with a clean cache
yt-dlp -4 --rm-cache-dir "https://youtu.be/dQw4w9WgXcQ"

Still blocked? Read on. The order matters: each step below is cheaper and safer than the next, and skipping to cookies first is the most common way to make the problem permanent.

What the error actually means

When yt-dlp asks YouTube for a video’s player data, YouTube scores the request: the IP address and its history, whether the client presents a valid Proof-of-Origin (PO) token, whether there is a session cookie, and how many requests came from that address recently. If the score is bad, YouTube answers with a login wall instead of the player response, and yt-dlp prints “Sign in to confirm you’re not a bot”. Nothing in your command is wrong; YouTube simply does not trust the source.

Why it happens — the four real triggers

  • IP reputation. Data-center ranges (every VPS, cloud instance and CI runner) are scored far below home connections. On our own extraction fleet in August 2026 roughly one in four fresh exit IPs hit the bot wall on first contact, and IPv6 was worse: YouTube scores a whole /64 as one unit, so one noisy neighbour flags the block.
  • No PO token. Since 2024 YouTube expects a Proof-of-Origin token minted by its BotGuard JavaScript. yt-dlp can only produce one with an external JS runtime (Deno, Node or Bun) or a PO-token provider plugin; without it some clients are refused outright.
  • No session. An anonymous request from a flagged IP looks exactly like a scraper. A cookie jar from a real browser session raises the score — which is why cookies “work”, and why they stop working when the IP is bad enough.
  • Volume. Dozens of requests per minute from one address, especially playlists and retry loops, trip rate-based scoring even on a clean IP.

Fix it in this order

1. Update to the latest release (or nightly)

YouTube changes its player and signature code every few weeks and yt-dlp ships matching fixes within days. A build older than a month fails in ways that look like a bot check. Distro packages lag badly — install with pip or the official binary and run yt-dlp -U.

2. Install a JavaScript runtime

Current yt-dlp needs an external JS runtime to solve YouTube’s challenges and mint PO tokens. Deno is the recommended choice; Node.js and Bun also work. Without one, yt-dlp warns about missing formats and often falls straight into the bot wall. Verify with yt-dlp -v and look for the runtime line in the debug header.

3. Force IPv4

yt-dlp -4 "https://youtu.be/dQw4w9WgXcQ"   # or: --force-ipv4

If your server has both address families, yt-dlp may go out over IPv6, where YouTube’s scoring is harsher (a /64 is judged as one unit). This one flag fixes a surprising share of “works on my laptop, fails on the VPS” cases, because laptops are usually IPv4-only behind a home router.

4. Cookies — from a throwaway session, never your main account

Cookies tell YouTube the request belongs to a real session. Export them from a private browsing window that is logged in to a spare Google account, then close the window so the browser does not rotate the session behind your back. Do not export cookies from your everyday account: repeated automated use from a flagged IP can get that account rate-limited or locked.

# export cookies.txt with a browser extension from the private window, then:
yt-dlp --cookies cookies.txt -4 "https://youtu.be/dQw4w9WgXcQ"

# or read them straight from a browser profile (works for one-off local use):
yt-dlp --cookies-from-browser chrome "https://youtu.be/dQw4w9WgXcQ"

Cookies are a patch, not a cure: they expire, and once the IP itself is flagged the session no longer helps. If cookies only work for a day or two, the problem is the address, not the cookie jar.

5. Add a PO-token provider

When the debug output says a client needs a PO token that yt-dlp could not obtain, install a provider plugin such as bgutil-ytdlp-pot-provider. It runs a small BotGuard service that mints tokens for yt-dlp automatically. This is the most reliable of the “stay on your own IP” fixes and the one most people skip.

6. Try another player client

yt-dlp --extractor-args "youtube:player_client=tv" "https://youtu.be/dQw4w9WgXcQ"
# also worth trying: android, mweb, web_embedded (each has its own format set)

YouTube scores each client differently and the list of trusted clients changes every few weeks, so treat this as a workaround. Some clients cannot deliver 1080p+ or need cookies of their own.

7. Change the IP: residential proxy or a different network

If a clean laptop on a home connection downloads the same video without cookies, the server’s IP is the problem and no flag will fix it. Route yt-dlp through a residential or mobile proxy with --proxy, or move the extraction to a machine with a cleaner address. Rotating cheap data-center proxies rarely helps — they are scored just like your VPS.

8. Slow down

yt-dlp --sleep-requests 2 --sleep-interval 5 --max-sleep-interval 15 --limit-rate 2M ...

Retry loops are the fastest way to turn a temporary challenge into a permanently flagged address. Back off, cap concurrency to one or two downloads, and never retry a bot-wall response in a tight loop.

Symptom → most likely cause

  • Works on your laptop, fails on the VPS → IP reputation (step 3, then 7).
  • Fails on every video after working yesterday → YouTube changed something; update (step 1) and check for a JS runtime (step 2).
  • Works with cookies for a day, then fails again → the IP is flagged; cookies cannot save it (step 7).
  • Only some videos or formats fail; -v mentions a PO token → PO-token provider (step 5) or another client (step 6).
  • Fails only during bulk runs or playlists → volume scoring (step 8).

Mistakes that make it worse

  • Using your personal Google account’s cookies on a server — the account, not just the IP, can get restricted.
  • Running yt-dlp as root with a shared, polluted cache; use --rm-cache-dir and a per-user cache.
  • Mixing a cookie jar with clients that are not meant to use cookies (yt-dlp warns about this) — you get the worst of both.
  • Retrying in a loop every few seconds after a challenge; wait minutes, not seconds, and change something between attempts.

When patching stops paying off

If yt-dlp powers a bot, an app or a pipeline rather than a one-off download, the wall becomes an operations job: cookie rotation, PO-token services, residential exits, nightly updates. A hosted API keeps all of that server-side and hands your code a URL:

curl "https://tunelio.dev/create?url=https://youtu.be/dQw4w9WgXcQ&quality=720p" \
  -H "Authorization: Bearer tnl_your_api_key"
# → { "url": "https://…/tunnel?id=…&sig=…", "file_size_str": "28.52 MB", "status": "ok" }

Tunelio is our own service, so weigh this section accordingly. The honest version: if you download a handful of videos a week from a home connection, keep yt-dlp — steps 1 to 3 will carry you. If you fight the wall every week on servers, the cheapest fix is to stop owning the problem. New accounts get 100 free credits, no card required.

Sources and further reading

  • yt-dlp wiki — “How do I pass cookies to yt-dlp?” and the PO token guide (github.com/yt-dlp/yt-dlp/wiki).
  • yt-dlp README — JavaScript runtime requirement for YouTube (Deno recommended).
  • bgutil-ytdlp-pot-provider — PO-token provider plugin.
  • Our own measurements (Tunelio extraction fleet, August 2026): share of fresh exits hitting the bot wall, IPv6 /64 scoring behaviour.

Frequently asked questions

Does adding cookies always fix it?

Often, but not for long. Cookies raise the trust score of a request, but they expire, and a badly flagged IP is challenged anyway. If cookies stop working after a day or two, the IP is the real problem.

Is it safe to use my own Google account’s cookies?

Not on a server. Automated use from a flagged address can get the account rate-limited or locked. Use a spare account in a private window, export once, and close the window.

Why does it work on my laptop but not on my server?

Your laptop sits on a home IPv4 address with a good reputation; the server is a data-center range (often over IPv6) that YouTube scores as a likely bot. Force IPv4 first, then consider a residential exit.

What is a PO token and do I need one?

A Proof-of-Origin token minted by YouTube’s BotGuard script to prove the client is a real browser. Some clients are refused without it. yt-dlp needs a JS runtime or a provider plugin to obtain one.

Will a hosted API hit the same wall?

It hits it on your behalf and handles it server-side — fresh sessions, PO tokens and residential IPs — so your code only ever sees a download URL.

Related guides