Guides · Updated 2026-10-25

yt-dlp Instagram "Login Required" Error on a Server

The script works on your laptop. You deploy it to a VPS, a Lambda or a Docker container, and Instagram downloads start failing with something like:

ERROR: [Instagram] DcTa7nogl9z: Requested content is not available, rate-limit reached or login required. Use --cookies, --cookies-from-browser, --username and --password, --netrc-cmd, or --netrc (instagram) to provide account credentials

instaloader users see the same thing in a different form: 401 Unauthorized with "Please wait a few minutes before you try again". It's rarely a bug in either tool.

Why it happens

  • Your IP is a datacenter IP. Instagram treats logged-out traffic from cloud providers far more strictly than traffic from home and mobile connections. The same command that works at home gets a login wall from AWS, GCP, Hetzner or DigitalOcean.
  • Rate limits are per IP and tight. A batch job that fetches a few dozen posts in a row trips them even from a good IP.
  • Instagram changes its web responses often. An old yt-dlp version can fail on content that a current one handles.

Fixes, roughly in order of effort

1. Update yt-dlp. Rule this out first:

yt-dlp -U            # standalone binary
pip install -U yt-dlp  # pip install

2. Slow down. Space out requests so a batch doesn't look like a burst:

yt-dlp --sleep-requests 2 --sleep-interval 5 --max-sleep-interval 15 -a urls.txt

3. Pass cookies from a logged-in account. This is the fix yt-dlp suggests, and it works:

# on a machine with a browser where you're logged in
yt-dlp --cookies-from-browser firefox --cookies cookies.txt --skip-download "https://www.instagram.com/reel/DcTa7nogl9z/"

# copy cookies.txt to the server
yt-dlp --cookies cookies.txt "https://www.instagram.com/reel/DcTa7nogl9z/"

The catch: the session is now tied to an Instagram account making automated requests from a server. Expect checkpoints ("confirm it's you"), expired cookies you have to refresh by hand, and on heavier use a suspended account. Never use your personal account for this.

4. Route through a residential proxy. --proxy http://user:pass@host:port with a residential or mobile IP gets you past the datacenter penalty. It works, but the proxy bill is per GB, video is heavy, and you still need step 1 and 2.

5. Hand the problem off. If downloading is a feature of your product rather than the product itself, a hosted API that resolves the URL for you removes the cookies, proxies and version chasing from your server.

Trade-offs

ApproachWorks from a VPSNeeds an Instagram accountOngoing upkeep
yt-dlp, logged outOften blockedNoFrequent updates
yt-dlp + cookiesUsually, until the session is flaggedYes, and it can get bannedRefresh cookies, replace accounts
yt-dlp + residential proxyMostlyNoProxy cost per GB, updates
Hosted API (soclip)YesNoNone on your side; $0.002 per lookup

Swapping yt-dlp for an API call

If you were calling yt-dlp to get a direct URL (yt-dlp -g) or the file, this is the equivalent:

curl -s -X POST https://api.soclip.dev/v1/media \
  -H "Authorization: Bearer $SOCLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://www.instagram.com/reel/DcTa7nogl9z/"}' \
  | jq -r '.data.medias[0].url' \
  | xargs -I{} curl -sL -o reel.mp4 "{}"

It handles Instagram, TikTok, X/Twitter and Facebook. It doesn't do YouTube — for YouTube, yt-dlp is still the tool. Sign in with GitHub at soclip.dev for 500 free credits (250 lookups); failed lookups aren't charged. Code for Python and Node.js.

500 free credits on signup — 250 lookups across Instagram, TikTok, X and Facebook. Credits never expire.

Related guides