node-ytdl-core: Preventing Error 429: Too Many Requests

I’m using ytdl-core from a browser, using browserify. Cross-domain requests are not allowed, so I’m using CORS Anywhere proxy to bypass CORS Header related errors.

After a few requests, I’m getting error 429s from YouTube, saying that I may be making too many requests (not really, one or two per minute at the most, downloading a webm stream). The method crashes afterward and won’t do any additional requests.

Google seems to block the entire origin domain, so it won’t work for anyone with the same origin header (I haven’t verified yet).

There are multiple things wrong:

  • How can I prevent this? I’d like to have some sort of rate throttling so it doesn’t incur into 429 errors. It renders ytdl completely unusable for a long time (no exact amount, last time it was more than an hour)
  • No error is thrown by ytdl whatsoever. This is not good because there is no way to handle the error. The callback never gets invoked, and error handlers are never called.

Code example:

const ytdl = require('ytdl-core');
const concat = require('concat-stream');
 var concatStream = concat((arrayBuffer) =>
        {
            console.log('file downloaded');
           // Processing of video blob goes here...
        });

        var ytstream = ytdl(YOUTUBE_VIDEOURL,
            {
                requestOptions: {
                    transform: (parsed) =>
                    {  
                        var parsedHeaders = parsed.headers;
                        return {
                            host: 'cors-anywhere.herokuapp.com/', 
                            path: "http://youtube.com" + parsed.path,
                            maxRedirects: 10,
                            headers: parsedHeaders
                        }
                    },
                },
            });

        ytstream.on('error', function(e)
        {
           // Never gets called
        })
        .pipe(concatStream);

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 17
  • Comments: 76 (16 by maintainers)

Most upvoted comments

  • How can I prevent this? I’d like to have some sort of rate throttling so it doesn’t incur into 429 errors. It renders ytdl completely unusable for a long time (no exact amount, last time it was more than an hour)

I’m going to be adding throttling so that it doesn’t make requests too fast to prevent these errors

  • No error is thrown by ytdl whatsoever. This is not good because there is no way to handle the error. The callback never gets invoked, and error handlers are never called.

will be fixed soon

I have a similar problem with my discord.js bot and ytdl by itself. If i use ytdl "anyurl" --print-url it throws the Error: 429. When i use ytdl-core for my discord bot, the bot joins but has no audio. The player doesnt receive any ytdl data. (buffer length: 0). The error started around 7 to 8 months using the bot on 1 Server.

Bottom line, for all you newcomers: 429 is YouTube trying to limit you. It is not a problem with the ytdl-core project. Our friend Promise in the Discord guild pointed out the following solutions:

  1. Make sure you’re at the latest version of ytdl-core
  2. Try using cookies (example in examples folder) This works quite well most of the time.
  3. Try using proxies (example in examples folder) This is difficult to set up but mostly foolproof
  4. Switch to IPv6 (if you aren’t already) Block-rotating is coming soon, plus it gives you a new address upfront.
  5. If all else fails, just wait between a few hours and a few days, and it will go away.

fent, I don’t know how GitHub Issues works, but perhaps place these pointers somewhere important so we don’t get more people asking the same question.

I’m using Heroku too and 429 still appears, even with cookies. Restarting prevents it for some time, but unfortunately is not a solution.

Same here. Getting a bursty stream of requests blocks all videos. Would love to see a correct cookie implementation

the way that console.log prints objects, it will put quotes around attribute names that contain a non-alphanumeric character, it does not affect the actual internal attribute name used.

as for why it’s not working and the error you’re getting, try lowercasing the header name to “cookie”.

if that doesn’t work, it’s likely that having that cookie there prevents the endpoint ytdl-core uses internally to work. you could try only setting the cookie during the download. something like

let info = await ytdl.getInfo(id);
ytdl.downloadFromInfo(info, { requestOptions: { Cookie: cookie } });

🎉 This issue has been resolved in version 4.11.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Nope,it isn’t fixed,I’m still getting the error.

The solution is to set cookies. How to get cookies?

navigate to YouTube in a web browser open up dev tools (opt+cmd+j on mac) go to the Network tab Click on a request on the left scroll down to “Request Headers” find the “cookie” header and copy its entire contents, That would be cookies

I’m getting the 429 status code too, sadly. This is what I get in console

Error: input stream: Status code: 429
at ClientRequest.<anonymous> (/home/container/node_modules/miniget/dist/index.js:150:31)
at Object.onceWrapper (events.js:417:26)
at ClientRequest.emit (events.js:310:20)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:603:27)
at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
at TLSSocket.socketOnData (_http_client.js:476:22)
at TLSSocket.emit (events.js:310:20)
at addChunk (_stream_readable.js:286:12)
at readableAddChunk (_stream_readable.js:268:9)
at TLSSocket.Readable.push (_stream_readable.js:209:10)

Are there any fixes for this?

Package Version: 3.2.2

@eric-mathison Were you able to make requests from a blocked IP?

I couldn’t confirm that my IP was blocked, but I kept getting error 429 from my node application running local on my laptop. I waited over 14 hours and it was still receiving this error. Passing those 3 cookies is working. I just finished downloading 52 videos in around 7 minutes time. They are small 75mb and I downloaded them slow, 1 at a time. So far so good.

Thank you for the speedy answer. I’m afraid this doesn’t work… I still get the 429 error but now I get it from the getInfo() function. I need to set cookie for every request that I send to youtube and I can’t find an example code anywhere online about setting cookies with ytdl-core that works 😦

Maybe you could add an example for cookies in the example folder than you have?

If you are not throttled by youtube with error 429 you can recreate the scenario trying to download a private video. Only when using cookies you will be able to get it.

I can confirm that it’s basicly the same becouse watchJSONPage is basicly just raw JSON from watchHTMLPage you can go to source of package and try it yourself. Basicly all of these 3 getWatchHTMLPage, getWatchJSONPage, getVideoInfoPage, Are the same. It returns same data.