Web Scraping CorePremium tier

How to Fix 403 and 429 Errors When Scraping

A 403 or 429 mid-crawl is rarely 'the site hates proxies' — it is usually one of four predictable failure modes with different fixes. This troubleshooting guide maps each status code to the signal it carries, the root cause behind it, and the rotation or credential change that actually resolves it.

TMWritten by Thomas Müller·Reviewed by Sarah Chen·Updated September 4, 2026
11 min read
Editorial board showing that HTTP 403 and 429 are different diagnoses, not one status-code fix.

Key takeaways

  • 403 Forbidden on scraping usually means reputation or fingerprint, not a missing API key — rotating to a fresh residential IP is the first move.
  • 429 is a velocity signal: back off with jitter and widen the pool; hammering the same URL from the same IP turns a throttle into a ban.
  • 407 almost always means malformed proxy credentials — fix the username format before blaming the target site.
  • 502 from the proxy gateway means the upstream exit failed; retry with a new IP, not the same session.
  • Log status code, exit country, and response body hash together — patterns in that tuple tell you which layer is failing.

On this page

Signal observed → what it means for your scraper

Match the signal you captured, then decide whether a residential proxy can change that layer before you rotate.

Signal observedWhat it indicatesWhich layerDoes a proxy change it
403Immediate Forbidden on first request or after a short burstIP reputation block, WAF rule, or TLS/HTTP fingerprint mismatch — datacenter ASNs and bare Python clients trip this fastestRotate to a fresh residential IP, send a complete browser-like header set, and for protected sites switch to curl_cffi or Playwright so the TLS fingerprint matches Chrome
429Too Many Requests after sustained crawling from few exitsPer-IP or per-subnet velocity exceeded — the target is asking you to slow down, not permanently banning yetExponential backoff with jitter, lower global concurrency, and per-request rotation so no single IP accumulates volume
407Proxy Authentication Required before the target is ever reachedWrong username/password, expired credential, or malformed targeting suffix in the proxy URLVerify dashboard credentials, ensure the format is http://USER:PASS@proxy.aethyn.io:PORT, and confirm country/session tokens have no illegal characters
502Bad Gateway from proxy.aethyn.io with no target HTML in the bodyThe selected exit node could not complete the upstream connection — transient node issue or blocked route to the target ASNRetry on a fresh IP (drop sticky session), reduce timeout pressure, and if persistent for one domain try a different country exit or Elite tier
Session rail where retrying the same IP after 429 turns a throttle into a ban.
Treat unknown 429 as fail-closed until you know if it is a challenge.

How to diagnose and fix this scraper failure

  1. 1

    Classify the error: proxy layer vs origin layer

    Before rotating anything, determine whether the response came from proxy.aethyn.io or the target host. A 407 or 502 with a proxy error body is infrastructure; a 403/429 with the target's HTML (or WAF challenge page) is the site. Log response.url, status, and the first 200 bytes of body on every failure — that tuple is your diagnosis key.

    Python (classify)
    def classify_error(resp, proxy_host="proxy.aethyn.io"):
        if resp.status_code == 407:
            return "proxy_auth"
        if resp.status_code == 502 and proxy_host in (resp.url or ""):
            return "proxy_upstream"
        if resp.status_code == 429:
            return "rate_limit"
        if resp.status_code == 403:
            return "forbidden"
      return "other"

    Field note: If your HTTP client swallows the proxy URL in logs, hit httpbin.org/ip through the proxy first. A 407 there confirms credentials before you burn time debugging the target.

  2. 2

    Fix 407 and 502 before touching rotation strategy

    407 means the gateway rejected auth — re-copy credentials from the dashboard and verify USER:PASS encoding. 502 means the chosen exit failed upstream — retry with a new IP (omit sticky session) and a sane timeout. Do not lower concurrency on 407; it will never help.

    cURL
    curl -x "http://aethyn-XXXXX-country-us:PASSWORD@proxy.aethyn.io:2099" \
      -w "\nHTTP %{http_code}\n" https://httpbin.org/ip

    Field note: Special characters in passwords must be URL-encoded in the proxy URL. A 407 that appears only for certain country suffixes often means an illegal character in the username string.

  3. 3

    Respond to 429 with backoff plus fresh IPs

    On 429, sleep with exponential backoff and jitter, then retry through a rotated residential IP. Lower global concurrency if 429s appear across many fresh exits simultaneously — that pattern means your aggregate velocity is too high, not that individual IPs are burned.

    Python (429 handler)
    import time, random, requests
    
    PROXY = "http://aethyn-XXXXX:PASSWORD@proxy.aethyn.io:2099"
    proxies = {"http": PROXY, "https": PROXY}
    
    def fetch(url, attempt=0):
        r = requests.get(url, proxies=proxies, timeout=30)
        if r.status_code == 429:
            time.sleep(min(60, 2 ** attempt) + random.random())
            return fetch(url, attempt + 1)
        return r

    Field note: Respect Retry-After when the header is present — some APIs encode the exact cooldown. Ignoring it and retrying at T+1s is how polite throttles become hard blocks.

  4. 4

    Address 403 with fingerprint and geo alignment

    When 403 persists on fresh residential IPs, the block is likely fingerprint or geography, not reputation alone. Align Accept-Language with -country-XX, send a full browser header set, and for Cloudflare-class targets use curl_cffi or Playwright so JA3 matches Chrome.

    Python (curl_cffi)
    from curl_cffi import requests as cffi
    
    PROXY = "http://aethyn-XXXXX-country-de:PASSWORD@proxy.aethyn.io:2099"
    r = cffi.get(
        "https://example.com",
        impersonate="chrome",
        proxies={"http": PROXY, "https": PROXY},
        timeout=30,
    )
    print(r.status_code)

    Field note: A 403 on the homepage but 200 on /robots.txt often means geo-fencing, not a full IP ban. Test a neutral path before declaring the exit dead.

  5. 5

    Detect soft blocks and alert on error-rate SLOs

    Not every block returns 4xx. Treat 200 responses missing expected selectors or shorter than baseline as soft blocks — log them alongside hard errors. Set an error-rate SLO (e.g. <2% 403/429 per hour) and page when it breaches so you catch drift before a week of bad data lands in production.

What goes wrong when this scraper fails

Your scraper was humming along at 200 OK and then, without warning, every worker starts returning 403 Forbidden or 429 Too Many Requests. Teams often respond by doubling concurrency or swapping one datacenter IP for another — which makes things worse. The status code is the site's way of telling you which detection layer fired, and each code wants a different response. Treating them all as 'get a new proxy' wastes time when the real issue is credentials (407), upstream routing (502), or a fingerprint that no IP can fix.

When residential proxies fix this — and when they cannot

Residential proxies address the two causes behind most 403/429 pairs: low-trust IPs and concentrated velocity. Per-request rotation spreads load so each exit stays near human-scale request rates, which is what 429 is asking for. When a 403 is reputation-driven, a fresh residential exit often clears it immediately — unlike rotating within the same datacenter /24. For 502s, rotation simply selects a healthier exit path without you touching application code.

Pool-choice form matching 403 reputation, 429 velocity, 407 credentials, and 502 upstream to Premium or Elite.
Premium for volume. Elite when city, ISP, or reputation is the constraint.

How Aethyn residential proxies help here

Most scraping error playbooks come down to credentials, rotation, and tier. Aethyn controls all three through the proxy username on one endpoint — no separate gateway per country.

  • Premium residential pool (port 2099) sized for high-volume crawls where 429 is the main risk
  • Per-request rotation by default so 429 back-off actually lowers per-IP velocity
  • Explicit country and session tokens in the username for geo-correct retries after 403
  • Elite tier upgrade path when 403 persists on Premium due to high-security targets
  • Standard http://USER:PASS@proxy.aethyn.io:PORT format — easy to validate when debugging 407

Best practices that keep scrapers reliable

  • Log status, proxy country, URL, and body fingerprint together on every failure
  • Fix 407/502 on the proxy path before tuning anti-bot strategy
  • Backoff with jitter on 429; never immediate retry on the same IP
  • Align geo headers with -country-XX when debugging 403
  • Detect soft blocks (200 with missing content) as first-class errors
  • Track error-rate SLOs and alert before datasets corrupt
  • Deduplicate URLs upstream and cache unchanged pages — a 429 often means you are re-hitting the same endpoint
  • Segment workers by target difficulty; don't send a hardened marketplace and an open blog through the same pool tier
  • Inspect the Server and X-Cache response headers to tell a proxy-edge failure from a target CDN block (e.g. Cloudflare) before you start rotating

Common mistakes that burn proxy budget

  • Retrying 429 instantly and escalating to permanent 403
  • Rotating IPs when the password is wrong (407)
  • Treating all 403s as 'bad IP' when fingerprint is the culprit
  • Ignoring Retry-After headers on rate-limited APIs
  • Monitoring status codes only and missing soft-blocked 200s
  • Scaling concurrency up when 429 appears — the opposite of what the site asked for

Common questions about this scraper problem

Is 403 always an IP ban?
No. 403 can mean WAF rule, geo-block, missing cookie, or TLS fingerprint rejection. Fresh residential IPs clear reputation-driven 403s; persistent 403 on every new IP points to fingerprint or geography mismatch.
How long should I wait after a 429?
Start with exponential backoff capped around 60 seconds plus jitter. Honor Retry-After when present. If 429s continue across many fresh IPs, lower global concurrency — the limit is aggregate, not per-IP.
What causes 407 Proxy Authentication Required?
Invalid username or password, URL-encoding issues in the credential string, or a malformed targeting suffix. Test against httpbin.org/ip through the same proxy URL to isolate auth from target problems.
Should I retry 502 errors?
Yes, on a fresh IP without the previous sticky session. 502 means the exit could not reach the origin — usually transient. If 502 persists for one domain across many exits, try a different country or Elite tier.
Why do I still see 403 with residential proxies?
Residential fixes reputation, not fingerprint. Python requests with a Chrome User-Agent still ships a Python TLS handshake. Use curl_cffi or a real browser for protected targets.
I get a 403 on /login after scraping other pages — is that an IP problem?
Usually not. A 403 that appears on an authenticated step like /login after /products already succeeded is typically a session problem, not IP reputation. Use a sticky session so the auth flow keeps the same exit IP and cookies across the multi-step sequence rather than rotating mid-flow.
What is a soft block?
HTTP 200 with challenge HTML, empty results, or content missing expected selectors. Status-code-only monitors miss it — validate content presence before accepting a response.
Which Aethyn tier for error-heavy scraping?
Premium on port 2099 handles most retail and catalog targets. Move to Elite (5499) when 403 persists on high-security sites like Cloudflare Enterprise or Amazon despite correct rotation.
Can I automate retry logic in my scraper framework?
Yes — centralize classification (407/502/429/403/soft) and branch handlers. Scrapy middlewares, httpx event hooks, or a thin wrapper around requests all work; the important part is different behavior per class, not one generic retry.
Share this article

Solve this with Aethyn residential proxies

Route your first request through rotating residential IPs in minutes, with transparent per-byte pricing.

All solutions