No KYC — no ID, no selfie, no documents. Pay in crypto: BTC, USDT, USDC, ETH, SOL, LTC
Language: English
Get started

Proxy error reference · Connection and TLS errors

Connection reset by peer (ECONNRESET) through a proxy

Socket error: the exact message in each tool, the likely causes in order, and the fix that works.

Last updated: · 5 min read

Quick answer

What does Connection reset by peer (ECONNRESET) mean with a proxy?

Connection reset by peer means the other end closed the TCP connection abruptly, with a reset instead of a normal close. Through CrawlRelay residential proxies, the usual causes are a reused keep-alive connection that went stale, an exit that dropped, or a target firewall that cuts connections. Retry safe requests on a new connection and do not keep idle connections too long.

Connection reset by peer (ECONNRESET) at a glance

ErrorConnection reset by peer (ECONNRESET)
TypeSocket error
Sent byThe network stack, after the other side closed the connection abruptly
Defined inTCP reset (RST segment): RFC 9293
Retry it?Yes, for safe requests, on a new connection
First checkSee whether resets follow idle reused connections or new ones

What does Connection reset by peer (ECONNRESET) mean?

TCP can end a connection gracefully or with a reset. A reset tells your machine that the other side discarded the connection, so any data in flight is lost. Python raises ConnectionResetError; Node.js raises ECONNRESET or 'socket hang up'.

The 'peer' is whoever your socket talks to directly, which is the proxy gateway. The reset can still originate further along the chain and be passed on.

What does a connection reset look like in Python, curl, Node.js and browsers?

The same failure prints differently in every tool. These are the messages to search your logs for:

  • Python: ConnectionResetError: [Errno 104] Connection reset by peer, or [WinError 10054] on Windows
  • requests: ConnectionError(ProtocolError('Connection aborted.', ConnectionResetError(...)))
  • Node.js: Error: socket hang up or read ECONNRESET
  • curl: curl: (56) Recv failure: Connection reset by peer

What causes a connection reset?

Most likely first:

  • Stale keep-alive connections. A pooled connection sat idle and was closed on the other side; the next request on it fails at once.
  • A dropped exit, which ends every connection that used it.
  • A target firewall that resets connections it does not like.
  • Long uploads or downloads cut by an idle limit somewhere on the path.

How do I diagnose a connection reset step by step?

  1. Check whether resets happen on the first request of a connection or after idle reuse.
  2. Count resets per host: one host means the target; all hosts means the path or the pool.
  3. Note the timing: resets after exactly N seconds idle point to an idle limit.
Test the failing URL with curl (HTTP port, verbose)
# Use the URL that fails; with https://api.ipify.org instead, you test the gateway alone.
# "HTTP/1.1 200 Connection established" first, then the site's own status: the site answered.
curl -v -x http://USERNAME:[email protected]:7777 https://TARGET_URL

# Same test through the SOCKS5 port, with DNS resolved at the exit
curl -v --socks5-hostname gw.crawlrelay.com:7778 --proxy-user USERNAME:PASSWORD https://TARGET_URL

How do I fix a connection reset?

  • Retry idempotent requests (GET, HEAD) once on a new connection.
  • Shorten idle reuse: close pooled connections that have been idle for more than a few seconds, or open a new connection per request when you need a new IP anyway.
  • End a sticky session that resets repeatedly and start a new one.
  • Slow down on hosts that reset under load.
Python: retry with Retry-After, exponential backoff and jitter
import random
import time

import requests

PROXY = "http://USERNAME:[email protected]:7777"
PROXIES = {"http": PROXY, "https": PROXY}
RETRY_STATUSES = {429, 502, 503, 504}


def fetch(url, attempts=5, timeout=(10, 30)):
    for attempt in range(attempts):
        try:
            r = requests.get(url, proxies=PROXIES, timeout=timeout)
        except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
            r = None  # dropped exit, reset or timeout: a new connection gets a new exit
        if r is not None and r.status_code not in RETRY_STATUSES:
            return r
        retry_after = r.headers.get("Retry-After", "") if r is not None else ""
        if retry_after.isdigit():
            wait = int(retry_after)
        else:
            wait = min(60, 2 ** attempt) + random.uniform(0, 1)
        time.sleep(wait)
    raise RuntimeError("giving up on %s after %d attempts" % (url, attempts))

Should I retry after a connection reset?

Retry a reset once for safe requests such as GET. Do not blindly retry POST requests that change data: the first one may have been processed. A burst of resets on one host means that host is cutting you off; lower the pace there.

How does Connection reset by peer (ECONNRESET) apply to CrawlRelay?

On CrawlRelay, rotation happens per new connection. A client that keeps one connection alive keeps the same exit for every request on it, so a dropped exit resets that connection. Reopen the connection to get a fresh exit; the sessions guide shows the patterns.

Gateway: gw.crawlrelay.com, port 7777 (HTTP, HTTPS through CONNECT) and port 7778 (SOCKS5). Username format: USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}. Related: 502 Bad Gateway · Read timed out · Sessions guide.

Connection reset by peer (ECONNRESET): questions developers ask

Why do I get 'socket hang up' in Node.js with a proxy?

The connection closed before a response arrived. With a proxy, common causes are a reused keep-alive socket that went stale, an exit that dropped, or a target that cut the connection. Retry GET requests on a new socket and limit how long idle sockets stay in the pool.

Is a connection reset a sign that I am blocked?

Sometimes. Firewalls can reset connections from clients they reject, but resets also happen for harmless reasons on any residential network. Look at the pattern: resets limited to one host and growing with your request rate suggest the host is pushing back.

Should I disable keep-alive for scraping?

Not completely. Keep-alive saves time when you send several requests to the same host through one sticky exit. When you want a new IP on every request, a new connection per request is the cleaner choice. Mixing both carelessly is what produces stale-connection resets.

Other proxy errors in this reference

HTTP status codes

Browser and client errors

Connection and TLS errors

Residential proxies with docs that cover the failure cases

CrawlRelay residential proxies from $0.50/GB, traffic that never expires.

From $0.50/GB · no KYC

Get started