Fix "HTTP Error 403: Forbidden" in yt-dlp
ERROR: unable to download video data: HTTP Error 403: Forbidden
Quick answer
A 403 from yt-dlp almost never means you are blocked. It means the download URL yt-dlp extracted was rejected when it went to fetch it — usually because the cached player it derived the URL signature from is out of date. Update, clear the cache, and try again:
yt-dlp -U && yt-dlp --rm-cache-dir && yt-dlp "URL"
Why a 403 happens
Downloading from YouTube is two separate steps, and the error comes from the second one. First yt-dlp fetches the watch page and extracts a list of media URLs. Those URLs are not permanent links to a file — each one carries a signature and an expiry timestamp, and the server checks both before serving a byte.
The signature is computed by JavaScript inside YouTube's player. yt-dlp downloads that player,
works out what the function does, and applies it locally. To avoid doing that on every run it
caches the result. When YouTube ships a new player — which happens often, and without notice —
the cached logic produces signatures the server no longer accepts. The server does not say
"your signature is wrong". It says 403 Forbidden.
That is the whole reason a 403 is so rarely about permissions. Nothing about your account, your IP or your right to view the video has changed. A link expired, or was computed with stale code.
The fixes, in the order worth trying
1. Update yt-dlp
If YouTube changed the player in a way yt-dlp cannot parse yet, no local fix helps — the extractor itself needs updating, and that update usually lands within a day or two. This is the first thing to rule out, and it takes ten seconds:
yt-dlp --version
yt-dlp -U
If -U replies that the binary cannot update itself, yt-dlp came from pip or a
package manager and has to be updated the same way. That distinction matters more than it
sounds — how you installed it decides how fast
extractor fixes reach you, and a distribution package can be a year behind.
2. Clear the player cache
This is the specific fix for a stale cached player, and it is the one that resolves most 403s that survive an update:
yt-dlp --rm-cache-dir
It deletes ~/.cache/yt-dlp (or %LOCALAPPDATA%\yt-dlp on Windows). There
is nothing precious in there — the next run rebuilds it. If you are scripting yt-dlp and hitting
intermittent 403s, running this weekly is cheaper than debugging it each time.
3. Stop naming an exact format
A selector pinned to a specific format id sends you to one particular host, and some of those have far shorter URL expiry than others. A selector with a fallback lets yt-dlp pick again:
yt-dlp -f "bv*[height<=1080]+ba/b[height<=1080]" "URL"
The / is the fallback and the * in bv* allows a combined
stream as well as a video-only one. Both are covered in
format selection, which is worth twenty
minutes if you use yt-dlp regularly.
4. Slow down
If the 403 appears part-way through a playlist rather than on the first video, it is a rate problem wearing a different error's clothes. Extraction is what gets throttled, and the symptom is inconsistent:
yt-dlp --sleep-requests 1.5 --limit-rate 2M -i "PLAYLIST_URL"
See HTTP Error 429 for the full set of pacing flags — those apply here too when 403s come in bursts.
5. Supply cookies
Last, not first. Cookies help when the content genuinely needs an account, and they do nothing for an expired URL. They also carry a real cost: a session sent through a downloader is a session that can get flagged.
yt-dlp --cookies-from-browser firefox "URL"
Confirming it worked
Do not test with a full download — a 4 GB file is a slow way to find out you are still broken.
--simulate runs the whole extraction, including the part that 403s, and writes
nothing:
yt-dlp --simulate -v "URL"
Clean output means the URLs extracted fine. If you still see the 403, the -v output
now has the two lines worth reading: the yt-dlp version, and the last line before the traceback.
If it still fails
A 403 that survives all five steps is usually not a 403 problem. Check which of these you actually have:
- Every video fails, immediately, on a fresh install. Something between you and YouTube is intercepting the connection — a corporate proxy, a filtering DNS, an antivirus TLS scanner. See certificate verify failed, which often accompanies it.
- Only age-restricted or members-only videos fail. That is an access problem that happens to surface as 403. Cookies are the answer, and the cookies guide covers getting them out correctly.
- It works for a while, then 403s consistently. Rate limiting. Wait an hour before concluding anything else — most soft blocks expire on their own.
-
Only one specific video. Try it in a browser. If it plays there and not in
yt-dlp, it is an extractor bug worth
reporting with the full
-voutput.
What not to do
Two pieces of advice circulate widely for this error and both are wrong.
--no-check-certificate disables TLS verification, which has nothing to do with an
HTTP 403 — it turns a security check off and fixes nothing. And a random
--user-agent string copied from a forum post makes things worse rather than better:
YouTube expects the user agent to match the client yt-dlp is claiming to be, and a mismatch is
one of the signals that triggers
the bot check.
Frequently asked
Does a 403 mean my IP is banned?
Why does --rm-cache-dir fix it?
I get 403 on some videos but not others.
Will a VPN fix a 403?
Related
- Fix "HTTP Error 429: Too Many Requests" in yt-dlp A 429 is a rate limit with a timer attached, and retrying immediately restarts it. How long the block actually...
- Fix "nsig extraction failed" and 50 KiB/s Downloads in yt-dlp The nsig warning is why your download crawls at dial-up speed instead of failing outright. What the n-paramete...
- yt-dlp Cookies: --cookies-from-browser vs cookies.txt Cookies are how yt-dlp proves it is you — for private videos, members-only content and bot checks. Both method...