Why Is My IP Getting Blocked?

A 403, a 429, a CAPTCHA and a decoy page each point at a different defense. Read the response, then work from the cheapest fix upward.

Start with the response the target sent. Each kind of refusal is a clue to which layer of the target's defenses reacted, and that decides what to try first. This guide covers the case where the connection built, the proxy accepted your credentials, and the target answered no. If the connection itself will not establish, see connection issues; if the proxy rejected you before the target saw the request, that is a 407 and its own guide applies.

Read the response before changing anything

Anti-bot systems are layered: reputation lists that score the address, rate counters that track volume, and behavioral or fingerprint scoring that looks at how the traffic presents. The shape of the block suggests which layer fired. Treat each as a likely cause to check, not a certain diagnosis; more than one can apply at once.

A 403 on the first request. Nothing about your behavior was evaluated yet, so the address itself was probably pre-classified. Datacenter ranges are public record, and protected targets score whole ranges. Pacing and header changes rarely move this outcome; the address class does. Confirm it with a residential exit (fix four) before spending time on the behavioral fixes.

A 403 after a run of successful requests. You were fine until a counter or score crossed a threshold. This is usually rate, pattern, or an accumulating fingerprint suspicion, and fixes one and two address it.

A 429. Explicitly about volume, often with a Retry-After header saying how long to wait, and it means the traffic was otherwise acceptable. Pacing fixes it.

A CAPTCHA. Suspicion rather than a verdict: the target is not sure you are automated, so it set a test. CAPTCHAs typically follow middling reputation or an inconsistent fingerprint. Solving them from automation is expensive; reducing the suspicion that triggers them is usually the better spend.

A 200 with the wrong content. Empty result sets, stripped listings, or altered prices served to suspected bots. Nothing looks broken, so the defense is validation: assert that expected fields exist, that values fall in sane ranges, and periodically compare a response with what a real browser sees.

No error, just slower and slower. Silent throttling. Rule out your own bottlenecks first (slow proxy speeds shows how to measure); a slowdown that affects one target and deepens over a session is likely the target's response to your traffic pattern.

Fix one: rate and rhythm

The cheapest fix, and the one to try first for anything behavioral. Set a per-domain request budget and keep concurrency against a single host modest; spreading load across targets is fine, concentrating it on one is what counters count.

Then look at rhythm. A request every 1.00 seconds all day is a pattern no person produces. Add jitter: randomize intervals within a band rather than sleeping a fixed duration. Honor Retry-After when a 429 supplies it, and back off exponentially when refusals repeat. A client that keeps retrying after a refusal can turn a temporary rate flag into a durable reputation entry.

Fix two: headers and fingerprint coherence

Default library headers announce automation: a python-requests user agent with a bare Accept: */*. Pasting in a Chrome user-agent string and nothing else can make matters worse, because the claim is now checkable and false. A real Chrome sends a coherent set (Accept, Accept-Language, Accept-Encoding and client-hint headers that agree with the browser being claimed). Borrow the complete header block from your own browser's devtools and keep it current as browser versions move. The user agent parser breaks a string into the browser, engine, version and platform a target reads from it, which catches a Chrome 118 string still being sent long after Chrome 118. To see what your client actually sends, inspect the headers your client sends; it reports the set as received and flags contradictions, at the HTTP layer only.

Below the headers is the TLS handshake. The ciphers a client offers, and their order, identify the underlying library before any HTTP header is sent, so a perfect Chrome header set on Python's TLS stack reads as a contradiction to a defense that checks. HTTP version compounds it: browsers negotiate HTTP/2 while many scraping stacks speak 1.1. When a target scores at this depth, the options are a client library that mimics a browser's handshake, or a real browser driven by automation; Puppeteer and Playwright covers wiring proxies into both.

Fix three: spread the load across more addresses

Rotation divides your request count across many addresses so each stays under per-IP thresholds. How aggressively to rotate depends on whether the target tracks state: logins, carts and multi-step flows break if the address changes mid-session, which is what sticky sessions are for. Sticky vs rotating sessions covers that trade-off, and the IP rotation guide covers the mechanics.

Rotation multiplies addresses, not credibility. If your client's fingerprint is what is being detected, a thousand exits produce a thousand detections. That is why rotation is the third fix rather than the first: fix the behavior, then spread it.

Fix four: change the address class

When first-request 403s persist however careful the traffic is, the likely verdict is on the address class, and the remedy is a different class. Datacenter IPs sit in allocations any defense can look up; they remain good value for the many targets that do not score them (internal tooling, most APIs, ad verification, the long tail of the web), which is how datacenter proxies are priced. Residential exits sit in consumer ISP space, where blanket blocking is costly for the target because it catches real customers, so defenses treat those addresses with more patience. That is what residential proxies sell, metered by bandwidth.

The economical pattern is a split rather than a wholesale move: route each target to the least expensive tier it tolerates, and spend residential bandwidth only where datacenter addresses are refused on sight. Which tier a target tolerates is measurable: block replay requests one URL from a datacenter exit and a residential exit at the same time and reports whether the two are answered differently. Choosing the right proxy type works through that decision target by target.

Fix five: make the geography coherent

Defenses cross-check where you claim to be against how you present. An exit in Germany sending Accept-Language: en-US only is a mild tell on its own and a stronger one combined with others. Match Accept-Language to the exit's country, its language first and English second. In browser contexts, timezone and locale deserve the same alignment. Choosing the exit country deliberately is done through username segments; country and city targeting has the grammar.

Geographic coherence also removes friction that only looks like blocking: currency redirects, consent walls and regional variants triggered by a mismatched exit can derail a scraper without any defense firing.

Some targets stay closed

A minority of targets refuse automated traffic whatever you change: sites behind login walls with per-account behavioral scoring, ticketing and limited-release retail, endpoints that challenge every automated-looking visitor on principle. The sign is that each fix buys less than the one before and block rates climb even as the traffic gets more careful.

At that point the question is economic: what is the data worth against what acquiring it costs? An official API, a commercial data feed, or simply less data may be the cheaper answer. In every case, cache what you have already fetched, skip pages that have not changed, and keep volumes proportionate to need; re-downloading unchanged pages spends your bandwidth allowance and the target's patience at the same time. Web scraping best practices covers the wider craft.

The order, condensed

Match the response to the first fix worth trying:

  1. 429: pacing and jitter. Stop there if it works; it usually does.
  2. 403 after success: pacing first, then header and fingerprint coherence.
  3. CAPTCHA: fingerprint coherence, then a real browser if the target scores TLS depth.
  4. First-request 403: address class; confirm with a residential exit before spending on behavioral fixes.
  5. Decoy content: validation immediately, then the full list, because you cannot fix what you cannot see failing.
  6. Silent throttling: measure to confirm, then treat as a 403 after success.

Each step costs more than the last (developer minutes, then developer hours, then metered residential traffic), so a cheaper step that works saves every step above it.