Respuesta rápida
¿Qué significa Connection reset by peer (ECONNRESET) con un proxy?
Conexión reiniciada por el par significa que el otro extremo cerró la conexión TCP abruptamente, con un reset en vez de un cierre normal. A través de proxies residenciales de CrawlRelay, las causas habituales son una conexión keep-alive reutilizada que quedó obsoleta, una salida caída, o un cortafuegos del destino que corta conexiones. Reintenta solicitudes seguras en una conexión nueva y no mantengas conexiones inactivas demasiado tiempo.
Connection reset by peer (ECONNRESET) en pocas palabras
| Error | Connection reset by peer (ECONNRESET) |
|---|---|
| Tipo | Error de socket |
| Enviado por | La pila de red, tras el cierre abrupto de la conexión por la otra parte |
| Definido en | TCP reset (RST segment): RFC 9293 |
| ¿Reintentar? | Sí, para peticiones seguras, en una conexión nueva |
| Primera comprobación | Comprueba si los reinicios siguen a conexiones reutilizadas inactivas o a conexiones nuevas |
¿Qué significa Connection reset by peer (ECONNRESET)?
TCP puede terminar una conexión de forma ordenada o con un reset. Un reset avisa a tu máquina que la otra parte descartó la conexión, por lo que cualquier dato en tránsito se pierde. Python lanza ConnectionResetError; Node.js lanza ECONNRESET o 'socket hang up'.
El 'par' es quien habla directamente con tu socket, es decir, el gateway proxy. El reset puede originarse más adelante en la cadena y transmitirse.
¿Cómo se ve a connection reset en Python, curl, Node.js y navegadores?
El mismo fallo se muestra de forma diferente en cada herramienta. Estos son los mensajes que debes buscar en tus registros:
- Python:
ConnectionResetError: [Errno 104] Connection reset by peer, o[WinError 10054]en Windows - requests:
ConnectionError(ProtocolError('Connection aborted.', ConnectionResetError(...))) - Node.js:
Error: socket hang uporead ECONNRESET - curl:
curl: (56) Recv failure: Connection reset by peer
¿Qué causa a connection reset?
Lo más probable al principio:
- Conexiones keep-alive obsoletas. Una conexión en pool estuvo inactiva y se cerró en el otro extremo; la siguiente petición falla inmediatamente.
- Una salida caída, que termina todas las conexiones que la usaban.
- Un cortafuegos del destino que reinicia conexiones que no le gustan.
- Subidas o descargas largas que se cortan por un límite de inactividad en el camino.
¿Cómo diagnostico a connection reset paso a paso?
- Revisa si los reinicios ocurren en la primera petición de una conexión o tras reutilizarla inactiva.
- Cuenta reinicios por host: un host indica el destino; todos los hosts indican el camino o el pool.
- Observa el tiempo: reinicios justo tras N segundos de inactividad señalan un límite de inactividad.
# 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¿Cómo soluciono a connection reset?
- Reintenta solicitudes idempotentes (GET, HEAD) una vez en conexión nueva.
- Reduce la reutilización inactiva: cierra conexiones pool que han estado inactivas más de unos segundos, o abre una conexión nueva por petición cuando necesites una IP nueva.
- Termina una sesión persistente que reinicia repetidamente y empieza una nueva.
- Reduce la velocidad en hosts que reinician bajo carga.
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))¿Debo reintentar después de a connection reset?
Reintenta un reset una vez para solicitudes seguras como GET. No reintentes ciegamente POST que cambian datos: la primera puede haberse procesado. Un pico de resets en un host indica que ese host te está bloqueando; reduce la velocidad allí.
¿Cómo se aplica Connection reset by peer (ECONNRESET) a CrawlRelay?
En CrawlRelay, la rotación ocurre con cada conexión nueva. Un cliente que mantiene una conexión viva mantiene la misma salida para cada petición en ella, así que una salida caída reinicia esa conexión. Vuelve a abrir la conexión para obtener una salida fresca; la guía de sesiones muestra los patrones.
Gateway: gw.crawlrelay.com, puerto 7777 (HTTP, HTTPS a través de CONNECT) y puerto 7778 (SOCKS5). Formato de usuario: USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}. Relacionado: 502 Bad Gateway · Tiempo de lectura agotado · Guía de sesiones.
Connection reset by peer (ECONNRESET): preguntas que hacen los desarrolladores
¿Por qué recibo 'socket hang up' en Node.js con un proxy?
La conexión se cerró antes de que llegara una respuesta. Con un proxy, causas comunes son un socket keep-alive reutilizado que quedó obsoleto, una salida caída o un destino que cortó la conexión. Reintenta solicitudes GET en un socket nuevo y limita cuánto tiempo permanecen inactivos los sockets en el pool.
¿Es señal de bloqueo una conexión reiniciada?
A veces. Los cortafuegos pueden reiniciar conexiones de clientes que rechazan, pero los reinicios también ocurren por motivos inocuos en cualquier red residencial. Observa el patrón: reinicios limitados a un host y que crecen con la tasa de peticiones sugieren resistencia por parte del host.
¿Debo desactivar keep-alive para scraping?
No completamente. Keep-alive ahorra tiempo cuando envías varias solicitudes al mismo host a través de la misma salida persistente. Cuando quieres una IP nueva en cada petición, una conexión nueva por petición es la opción más limpia. Mezclar ambos sin cuidado produce esos reinicios por conexión obsoleta.
Otros errores de proxy en esta referencia
Códigos de estado HTTP
- 401 Unauthorized vs 407
- 403 Forbidden
- 407 Proxy Authentication Required
- 429 Too Many Requests
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
Errores de navegador y cliente
Errores de conexión y TLS
Proxies residenciales con documentación que cubre los casos de fallo
CrawlRelay proxies residenciales de 0,50 US$/GB, tráfico que nunca expira.