
Web scraping developers, cross-border e-commerce sellers, SEO analysts, ad-verification teams, and data professionals often encounter the error received http code xxx from proxy after CONNECT. It appears when a proxy server can’t establish a CONNECT tunnel to the target site and returns an HTTP status code instead of HTTP/1.1 200 Connection Established, for example 407, 403, 429, 502, or 503.
This guide explains what the message means, why it appears in different situations, and how to fix the most common codes step by step. You will also learn practical ways to prevent repeat failures by selecting the right proxy protocol, managing concurrency and rotation, and choosing reliable proxy service.
A CONNECT request tells a proxy to open a tunnel to a target host and port. When the proxy accepts the request, it creates a TCP tunnel and replies with
HTTP/1.1 200 Connection EstablishedCONNECT is mainly used for HTTPS so the TLS handshake can pass through the tunnel. After the 200 reply, the TLS handshake begins and encrypted traffic flows through.
If the proxy blocks or fails to create the tunnel it does not return 200. It sends another HTTP status code such as 407, 403, or 502. These codes come from the proxy itself, not from the target site. Once the proxy has returned 200, any later status such as 301 or 404 originates from the target site and travels back through the tunnel.
Key points:
CONNECT builds a tunnel between client and target
Normal flow → 200 Connection Established
Error flow → proxy returns an HTTP code that explains the reason
Before the 200 response, status codes come from the proxy
After 200, they come from the target site.
Quick test with curl:
curl -v -x http://user:[email protected]:32345 https://example.com/Note: In curl, user:pass is your proxy username and password. If your proxy does not require authentication, you can omit user:pass@. In this tutorial, the proxy server address is shown as geo.ipcook.com, 32345 is the proxy port number, and https://example.com/ is just a placeholder for the target site you want to reach.
When a proxy fails to establish a CONNECT tunnel, it returns an HTTP status instead of 200 Connection Established. Below are the most common error codes, their meaning, and how to fix them.
You see 407 during CONNECT. It means the proxy expects credentials but did not get valid ones, or your IP is not on the allow list. This code is returned by the proxy itself before the tunnel is opened.
How to fix: 1. Add a correct username and password or add your IP to the allow list
2. Test with curl:
curl -v -x http://user:[email protected]:32345 https://example.com/Look for
HTTP/1.1 200 Connection Established3. Test with Python:
import requests
proxies = {
"http": "http://user:[email protected]:32345",
"https": "http://user:[email protected]:32345"
}
r = requests.get("https://example.com", proxies=proxies, timeout=15)
print(r.status_code)
You see 403 during CONNECT or on the first request after the tunnel opens. It means a policy or region rule denies the request, or the node or your IP has poor reputation. If 403 appears before 200, it comes from the proxy. If it appears after 200, it comes from the target site.
How to fix:
1. Switch to a clean node or a different region.
2. Update the allow list and account rules.
3. Verify reachability with a simple endpoint:
curl -v -x http://user:[email protected]:32345 https://httpbin.org/ipYou may see 429 Too Many Requests from the proxy before 200 or from the site after 200. This usually means your request rate or concurrency is too high and you’ve hit rate limits. It is common in web scraping when requests arrive too quickly.
How to fix:
1. Lower concurrency and add short delays with jitter.
2. Enable IP rotation to spread traffic across many addresses.
3. Add retry with exponential backoff for non-critical calls.
import time, random, requests
proxies = {
"http": "http://user:[email protected]:32345",
"https": "http://user:[email protected]:32345"
}
urls = ["https://example.com/page1", "https://example.com/page2"]
for url in urls:
# smooth bursts with a small delay and jitter
time.sleep(0.3 + random.random() * 0.4)
# capped retry with backoff for 429
for i in range(3):
resp = requests.get(url, proxies=proxies, timeout=15)
print("status", resp.status_code)
if resp.status_code != 429:
break
# honor Retry-After if present, else exponential backoff with jitter
ra = resp.headers.get("Retry-After")
delay = int(ra) if ra and ra.isdigit() else 2 ** i + random.random()
time.sleep(delay)You may get 502 or 503 during CONNECT or immediately after the tunnel opens. This usually points to an unstable proxy node, an upstream route issue, or the target site being down or under maintenance. These errors are often temporary but may repeat under load.
How to fix:
1. Retry with exponential backoff and reduce bursts:
curl -v --retry 3 --retry-delay 2 -x http://user:[email protected]:32345 https://example.com/2. Switch to another node or region and verify node health:
curl -v -x http://user:pass@new-proxy:new-port https://httpbin.org/status/2003. Compare via proxy and direct to isolate the issue:
# via proxy
curl -I -x http://user:[email protected]:32345 https://example.com/
# direct
curl -I --max-time 10 https://example.com/Interpretation:
If the proxy returns 5xx and direct returns 2xx or 3xx → the issue is on the proxy side.
If both paths return 5xx → the target site is down.
If the proxy returns 2xx and direct fails → the local network or region is blocking direct access.
Not every error is about authentication or rate limits. Some codes reflect the target site. Here is how to handle the common ones.
You request a page and get a redirect. This comes from the target site and the proxy only forwards it. Redirects are common when a site moves from http to https or changes a path.
How to fix: 1. Follow redirects in your client.
curl -L -x http://user:[email protected]:32345 https://example.com/import requests
proxies = {
"http": "http://user:[email protected]:32345",
"https": "http://user:[email protected]:32345"
}
r = requests.get("https://example.com", allow_redirects=True, timeout=15, proxies=proxies)
print(r.url, r.status_code)2. If you must keep the original method on redirect configure your client to preserve it where supported.
3. Verify the final URL and status to confirm you landed on the intended page.
You send a request and the server replies with 400 Bad Request. Usual causes include a wrong proxy scheme, a wrong port, or a malformed request line. Mixing an http proxy with SOCKS5 is a frequent mistake.
How to fix:
1. Verify the proxy scheme and port, then test with a simple endpoint:
curl -v -x http://user:[email protected]:32345 https://httpbin.org/ip2. Check the URL and headers for typos or illegal characters.
If you use SOCKS with curl, set the correct scheme:
curl -v -x socks5h://user:[email protected]:32345 https://httpbin.org/ip3. In Python requests, confirm the proxies dict matches the protocol:
import requests
proxies = {
"http": "http://user:[email protected]:32345",
"https": "http://user:[email protected]:32345"
}
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.status_code, r.text)You request a resource and get 404 Not Found. This means the resource does not exist at that path. Once the proxy returns 200 Connection Established, any later status such as 404 comes from the target site, not from the proxy.
How to fix: 1. Confirm the exact path, case, and trailing slash:
curl -I -x http://user:[email protected]:32345 https://example.com/
curl -I -x http://user:[email protected]:32345 https://example.com/path/2. Start from the home page, then add the path step by step.
3. If the resource needs login or region access, authenticate or switch to the right region, then retry:
import requests
proxies = {
"http": "http://user:[email protected]:32345",
"https": "http://user:[email protected]:32345"
}
r = requests.get("https://example.com/path/", proxies=proxies, timeout=15)
print(r.status_code, r.url)Common pitfall: A missing trailing slash or a case mismatch often causes 404. Always use the exact path the site expects.
Most proxy errors can be avoided. With careful configuration and a stable provider, you can reduce failures and keep long-running jobs smooth.
1. Control request rate: Avoid sending bursts. Add small delays with jitter and limit concurrency. This helps prevent 429 Too Many Requests and reduces 502 or 503.
2. Use IP rotation: Rotate addresses for large tasks to avoid bans. Use sticky sessions when you need the same IP for login or checkout flows.
3. Match protocol and scheme: Always set the correct proxy type for your client. Use HTTP, HTTPS, or SOCKS5 as required. A mismatch often leads to 400 Bad Request.
4. Add retries with backoff: Enable retry policies in your client. Use exponential backoff to recover from temporary failures such as 502 or 503.
Many recurring errors are caused by proxy infrastructure rather than your client settings. With unstable or low quality proxies you may still see 403 or 502 or 503 no matter how carefully you configure requests. IPcook provides a strong baseline that reduces these errors at scale.
What you get with IPcook:
Over 55 million real residential IPs
Coverage in more than 185 locations
Automatic IP rotation and sticky sessions up to 24 hours
99.99% uptime for reliability
Optimized routing for smooth, large-scale scraping and automation
In summary, start with the CONNECT step, map each status code to its cause, and apply the matching fix. Verify with simple curl tests, use the right authentication and protocol, tune rotation and concurrency, and monitor status codes over time. With a reliable residential proxy backbone, you’ll see fewer 407, 403, 429, and 5xx, and your jobs will stay stable at scale. Choose IPcook for residential IPs with automatic rotation, sticky sessions, global coverage, and low-latency routing to keep automation smooth.