Skip to content

Start typing. Errors match on their exact yt-dlp output.

to move, to open esc to close

Fix "Permission denied" Reading Browser Cookies in yt-dlp

Tested on yt-dlp 2026.07.28 Updated
What yt-dlp prints
ERROR: unable to open cookie file: PermissionError(13, 'Permission denied')
# or, on Linux with a Chromium browser:
ERROR: Failed to decrypt with DPAPI. See https://github.com/yt-dlp/yt-dlp/issues/7271

Quick answer

The cookie file exists and yt-dlp cannot read it — a different problem on each OS. On Linux it is the desktop keyring holding the decryption key; on macOS, Keychain; on Windows, a file lock. The one route that works everywhere is to stop reading the browser and export instead:

works on every OS, and from cron
yt-dlp --cookies cookies.txt "URL"

Linux: the keyring

Chromium browsers on Linux encrypt cookie values with a key kept in the desktop keyring — GNOME Keyring or KWallet. yt-dlp can read the database, gets ciphertext, and has to ask the keyring to decrypt it. That request fails when the keyring is locked, when there is no desktop session, or when D-Bus is not reachable.

Tell yt-dlp which keyring to use:

bash
yt-dlp --cookies-from-browser "chromium+gnomekeyring" "URL"
yt-dlp --cookies-from-browser "chromium+kwallet" "URL"

Under SSH with no session bus, the keyring is simply not there. Either export to a file, or use Firefox — its cookie file is not keyring-encrypted, which makes it the reliable choice on headless machines:

bash
yt-dlp --cookies-from-browser firefox "URL"

macOS: Keychain

Safari and Chrome both keep their key in Keychain, and macOS prompts for permission the first time yt-dlp asks. If the prompt was dismissed, the denial is remembered and yt-dlp fails silently from then on.

Open Keychain Access, search for Chrome Safe Storage, and check its Access Control tab — the denial is recorded there and can be removed. Then retry.

Safari needs Full Disk Access granted to your terminal, under System Settings → Privacy & Security. It is a broad permission to hand a terminal; Firefox avoids the question entirely.

Windows: locks and DPAPI

On Windows, "permission denied" is usually a lock rather than a permission. Close the browser properly — including background processes — and retry. If the error mentions DPAPI, the browser is Chrome 127 or newer and the encryption is bound to the browser process; no amount of permission fixes that. The Chrome cookie database page covers that case in full.

The approach that always works

Export once, in the browser, where the key is available. Install a cookies.txt exporter extension, export while signed in to the site, and pass the file:

bash
yt-dlp --cookies ~/cookies.txt "URL"

Then set permissions so the file is not readable by other accounts on the machine:

bash
chmod 600 ~/cookies.txt

Confirming it worked

bash
yt-dlp --cookies cookies.txt --simulate -v "URL"

Verbose output reports the cookie count. Zero from a file means the export produced a header and nothing else — a common outcome when the export was done from a page other than the site you need cookies for.

If it still fails

  • "does not look like a Netscape format cookies file". The exporter produced JSON. Use one that offers Netscape format explicitly — yt-dlp reads only that.
  • Cookies load, access still refused. The session is valid and lacks permission, or the account is not the one with access. See private video.
  • Worked, then stopped after a few days. Exported cookies expire. Sessions are rotated, and YouTube rotates them faster for accounts it considers unusual. Re-export.
  • Inside Docker. There is no browser and no keyring in the container. Mount a cookies.txt read-only — the Docker guide shows the volume.

Frequently asked

Why does yt-dlp need my keyring?
Chromium browsers on Linux encrypt cookie values with a key stored in the desktop keyring. Reading the cookie file gets you ciphertext; decrypting it requires that key, and asking the keyring for it is what triggers the prompt or the failure.
It works in my terminal but not from cron.
A cron job has no desktop session, so there is no keyring to unlock and no Keychain to prompt against. Export to a cookies.txt once and point the scheduled job at the file — it is the only approach that works without a logged-in session.
Can I run yt-dlp with sudo to get past this?
No — it makes it worse. Under sudo, yt-dlp looks for root's browser profile and root's keyring, neither of which contains your cookies. It also leaves root-owned files in your download folder.
Is a cookies.txt file less secure than reading the browser directly?
It is a plain-text copy of a live session, so yes, while it exists. The mitigation is to treat it as a credential: keep it out of synced folders and version control, and delete it when the job is done.