What do HTTP status codes mean in web scraping?
TL;DR
Every failed scrape arrives as a status code, and the code tells you who rejected you. The 4xx family means the request itself was refused, usually on identity or credentials. The 5xx family means something broke after the request was accepted, either at a proxy or at the origin. Reading the family first, then the specific code, is faster than guessing, because the fix for a 407 takes one line and the fix for a 503 may be an hour of waiting.
Reading the code before reacting
Three questions, in order:
- Who answered? A 407 comes from your proxy. A 502 or 504 comes from a gateway between you and the site. A 403 or 401 comes from the site. The response headers usually name the responder.
- Is it about you or about them? 4xx says the request was rejected. 5xx says the server failed. Retrying helps the second far more than the first.
- Does a browser see the same thing? If a page loads by hand while your client gets errors, the code describes your request rather than the site's health.
The codes a scraper actually meets
Not every status code shows up in scraping. These are the ones that do.
| Code | Who answered | Usual meaning here |
|---|---|---|
| 200 | The site | Success, though a block page can also arrive as 200 |
| 401 | The site | Credentials required or a session expired |
| 403 | The site | Refused on identity. See 403 in web scraping |
| 406 | The site | Your Accept headers did not match what it serves |
| 407 | Your proxy | Proxy credentials missing or wrong |
| 408 | The site | The request took too long to arrive |
| 410 | The site | The page is gone permanently, useful during crawls |
| 413 | The site or API | The request or response body was too large |
| 429 | The site | Rate limited. See bypassing 429 |
| 444 | Nginx | Connection closed with no response, often anti-bot |
| 451 | The site | Blocked for legal or regional reasons |
| 499 | Nginx | The client disconnected first. See error 499 |
| 500 | The site | The origin threw an error |
| 502 | A gateway | An upstream server gave an invalid response |
| 503 | The site | Overloaded, in maintenance, or an anti-bot rejection |
| 504 | A gateway | An upstream server did not answer in time |
| 520 | Cloudflare | The origin returned something Cloudflare could not read |
| 522 | Cloudflare | Cloudflare could not reach the origin at all |
Cloudflare also issues its own 1xxx error numbers on the block page rather than in the status line. Those are covered on the blog, starting with error 1015.
The trap worth knowing
A successful status code does not guarantee useful content. Many anti-bot systems return 200 with a challenge or interstitial page, so a pipeline that only checks status == 200 will happily store thousands of block pages and report success. Check the body as well as the code, at minimum for expected content on the page.
Key takeaways
Read the family before the number: 4xx means your request was refused, 5xx means something failed after it was accepted. Identify who answered, since a proxy error and a site error look similar in logs and have nothing in common as problems. And do not trust a 200 on its own, because a block page can carry one.
Go deeper on the blog
In the docs
Last updated: Aug 16, 2026