How to Fix a 429 Too Many Requests Error
Checks that show which limit you hit, three fixes in order, and retry code for cURL, Python and Node.js.
Updated
TL;DR
429 Too Many Requests means the website or API you called got more requests from you than it allows in a set time, so it refuses new ones for a while. Stop retrying, wait the time in Retry-After or at least a minute, then send requests more slowly.
What a 429 looks like in each client
Chrome draws its own error page only for a 429 with an empty body and otherwise shows the site's page.
| Where | What you see |
|---|---|
| Chrome, 429 with an empty body | This page isn't working. If the problem continues, contact the site owner. HTTP ERROR 429 |
| curl -i over HTTP/1.1, or any raw HTTP/1.1 response | HTTP/1.1 429 Too Many Requests |
| curl --fail | curl: (22) The requested URL returned error: 429 |
| Node.js with axios | AxiosError: Request failed with status code 429 |
| Python urllib, and yt-dlp on YouTube | HTTP Error 429: Too Many Requests |
| Google Cloud APIs, JSON error body | "code": 429, "status": "RESOURCE_EXHAUSTED" |
Why this happens
The site counts your requests, and you went over the number it allows.
Sites usually count by IP address, and APIs often by key or login, per second, hour or day. A common trigger is a script that runs requests in parallel or retries each 429 at once.
Diagnose your 429 first
These checks show who set the limit and what it counts.
Read the error page in your browser; if it says Error 1015, the site's owner set a Cloudflare rate limiting rule.
Read a Google API's JSON error; RESOURCE_EXHAUSTED can mean a spent quota, which retries may not clear for hours.
Send the requests one at a time; if they pass, the limit is on speed or parallel requests (GitHub allows 100), not a daily quota.
Ask whether coworkers or other apps on your network or API key get 429 too; if they do, you share one count.
Behind a proxy, run curl -v; CONNECT tunnel failed, response 429 means the proxy refused you, and a 429 through the tunnel is the site's.
Solutions ranked by effectiveness
Work down the list; the later fixes matter when slowing down is not enough.
- Most common fix
Wait for Retry-After, then retry slowly
Applies to scripts and apps. Pause for at least the seconds in Retry-After, otherwise for a wait that doubles after each 429, and stop after five tries.
curl -sS --retry 4 --retry-max-time 300 \ -o items.json -w '%{http_code}\n' \ https://api.example.com/items - Check next
Turn off the VPN or free proxy
Applies when you browse through a VPN or a free public proxy. Their exit IPs are shared, so the site counts other users' requests as yours.
Disconnect the VPN app and disable proxy extensions in your browser.
Clear any free proxy you entered in your system network settings.
Keep them off for this site instead of trying other servers or countries.
- For developers
Use the official API or ask the owner
Applies when your job needs more than the limit allows. Ask the owner for more; never split the job across extra keys, accounts or IPs.
Switch from loading pages to the site's official API where one exists.
Send your token; GitHub allows 60 requests an hour without one and 5,000 with it.
Request a higher quota, stating your app's purpose and calls per second and per day.
For sites without an API, ask the owner whether they offer a data feed.
Stop the 429 from coming back
Habits that cut requests and pace the rest, for jobs that call the same site or API every day.
Cache responses and resend the ETag in If-None-Match; GitHub does not count a 304 on an authorized request.
Use webhooks where the service offers them instead of polling for changes.
Set each job's concurrency from the published limit, not by raising it until 429s appear.
Log the share of 429s per host and pause the job automatically when it climbs.
Related errors
Learn more
FAQ
One IP an owner can allowlist
If the owner allows more for your Dedicated IP, no one else shares the exception.


