How to Fix ECONNRESET (Connection Reset by Peer)
Tell a stale keep-alive connection from a proxy or server drop, then fix it in Python, Node.js or cURL.
Updated
TL;DR
ECONNRESET, or connection reset by peer, means the server or proxy at the other end aborted an open TCP connection and your operating system reported it to your client. The fastest fix is to send a GET or other idempotent request again, once, over a fresh connection.
What ECONNRESET looks like in each client
The error number depends on the system: 54 on macOS, 104 on Linux, 10054 on Windows.
| Where | What you see |
|---|---|
| Node.js http and https (errno, code and syscall printed below) | Error: read ECONNRESET |
| Node.js http, reset during the response body (code ECONNRESET) | Error: aborted |
| Node.js fetch() (err.cause is Error: read ECONNRESET) | TypeError: fetch failed |
| axios in Node.js, as console.log prints it | AxiosError: read ECONNRESET |
| Python requests on Linux | requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) |
| Python on Windows | ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host |
| curl | curl: (56) Recv failure: Connection reset by peer |
Why this happens
The other side tore the connection down instead of ending it the normal way.
Usually the server or proxy timed out or restarted and no longer knows the connection, so when your client sends data on it, the far end answers with a TCP reset (RST).
Diagnose your ECONNRESET first
Each check points to one cause: a stale pooled connection, the proxy route, or the server itself.
Read the word before ECONNRESET; read means the reset arrived while your client was receiving, write means while it was still sending.
In Node.js, log req.reusedSocket in the error handler; if it is true, the server likely closed a pooled keep-alive connection as you reused it.
Send the same request without the proxy; if only proxied requests reset, look at the proxy route rather than the site.
Run curl -v through the proxy to an https:// URL; a reset before the CONNECT reply means the proxy hop dropped you.
If you run the server, check its log at the failure time; a crash or restart there explains resets on every open connection.
Solutions ranked by effectiveness
Start with the retry; the other two remove the usual reasons a connection gets reset.
- Most common fix
Retry once on a fresh connection
Applies when resets come and go. Repeat GET, PUT or DELETE one time, but not a POST that may already have run; curl repeats a reset only with --retry-all-errors.
import urllib.error import urllib.request url = "https://example.com/" for attempt in (1, 2): try: with urllib.request.urlopen(url, timeout=30) as r: print(r.status, len(r.read()), "bytes") break except (ConnectionResetError, urllib.error.URLError) as e: if attempt == 2 or not isinstance(getattr(e, "reason", e), ConnectionResetError): raise - Check next
Drop idle connections before the server does
Applies when requests after a pause fail. Give your keep-alive agent a timeout below the server's idle limit; Node.js 20 and later lower it further if the server's Keep-Alive hint is shorter.
const https = require("node:https"); const agent = new https.Agent({ keepAlive: true, timeout: 1500 }); function get() { https.get("https://example.com/", { agent }, (res) => { res.resume(); res.on("end", () => console.log(res.statusCode, "reused connection:", res.req.reusedSocket)); }).on("error", (err) => console.log("failed:", err.code)); } get(); setTimeout(get, 3000); - If nothing else works
Repair the proxy route
Applies when proxied requests reset on more than one site while direct ones work. Geonode's docs name unstable internet and wrong proxy settings as the most common causes of dropped proxy connections.
Copy host, port and login again from your proxy dashboard and replace the saved entry.
Test the same proxy on another device or network to rule out your connection.
Run fewer threads per proxy; Geonode's docs warn that too many can overload proxies.
Stop the ECONNRESET from coming back
Habits for uploads, Node.js upgrades and servers you run, so connections close cleanly.
For large uploads, send Expect: 100-continue, so the server can refuse before the body goes out.
Retest scripts after moving up from Node.js 18; from version 19 the default agent keeps connections open for reuse.
Before a deploy stops your Node.js server, call server.close(), which closes idle connections and lets busy ones finish.
On servers you run, close in stages (write side first), so a reset cannot erase your last reply.
Related errors
Learn more
FAQ
Help tracing dropped connections
Geonode's support team helps diagnose connection issues; include the failing request's details.


