redis/redis-py · error · ConnectionError
Error {err_no} while writing to socket. {errmsg}.
Error message
Error {err_no} while writing to socket. {errmsg}. What it means
Raised as a ConnectionError from send_packed_command() when the underlying write raises an OSError (other than a timeout). The errno and message are extracted from e.args; the connection is disconnected (nowait=True). This is the generic 'broken socket while writing' failure covering EPIPE, ECONNRESET, EBADF, etc.
Source
Thrown at redis/asyncio/connection.py:1201
command = [command]
if self.socket_timeout:
await asyncio.wait_for(
self._send_packed_command(command), self.socket_timeout
)
else:
self._writer.writelines(command)
await self._writer.drain()
except asyncio.TimeoutError:
await self.disconnect(nowait=True)
raise TimeoutError("Timeout writing to socket") from None
except OSError as e:
await self.disconnect(nowait=True)
if len(e.args) == 1:
err_no, errmsg = "UNKNOWN", e.args[0]
else:
err_no = e.args[0]
errmsg = e.args[1]
raise ConnectionError(
f"Error {err_no} while writing to socket. {errmsg}."
) from e
except BaseException:
# BaseExceptions can be raised when a socket send operation is not
# finished, e.g. due to a timeout. Ideally, a caller could then re-try
# to send un-sent data. However, the send_packed_command() API
# does not support it so there is no point in keeping the connection open.
await self.disconnect(nowait=True)
raise
async def send_command(self, *args: Any, **kwargs: Any) -> None:
"""Pack and send a command to the Redis server"""
await self.send_packed_command(
self.pack_command(*args), check_health=kwargs.get("check_health", True)
)
@deprecated_function(
version="8.0.0", reason="Use can_read() instead", name="can_read_destructive"View on GitHub (pinned to da03cdc7e8)
Solutions
- Wrap command execution in retry logic (the client supports retry_on_error / a configured Retry with backoff).
- Ensure firewalls/load balancers send keepalives or raise their idle timeout; enable socket_keepalive on the client.
- Set a health_check_interval so dead connections are detected before command use.
- Inspect the reported errno (ECONNRESET vs EBADF vs ENETUNREACH) to pinpoint server vs network vs local-state.
Example fix
// before r = redis.asyncio.Redis(host=h, port=p) // after from redis.backoff import ExponentialWithJitterBackoff from redis.retry import Retry retry = Retry(ExponentialWithJitterBackoff(), 3) r = redis.asyncio.Redis(host=h, port=p, retry=retry, retry_on_error=[ConnectionError])
Defensive patterns
Strategy: retry
Try / catch
from redis.exceptions import ConnectionError
for attempt in range(3):
try:
await r.set("k", "v")
break
except ConnectionError as e:
if "while writing to socket" in str(e):
await asyncio.sleep(2 ** attempt)
continue
raise Prevention
- Configure retry_on_error=[ConnectionError] with backoff.
- Enable socket_keepalive and health_check_interval.
- Watch for firewall idle-timeout RSTs.
When it happens
Trigger: Any send_command/send_packed_command where writer.writelines/drain raises OSError: writing to a connection the server already closed (EPIPE/ECONNRESET), a connection whose socket was closed locally (EBADF), or an OS-level IO error.
Common situations: Server restarted/crashed mid-session; a firewall/ELB idle timeout silently dropped the connection and the kernel only reports it on the next write; client-side disconnect racing with a command; running against an ACL-disabled or memory-evicted connection; ephemeral-port exhaustion.
Related errors
- Error while reading from {host_error} : {e.args}
- Timeout writing to socket
- Error {errno} while writing to socket. {errmsg}.
- Connection closed by server.
- Timed out closing connection after {self.socket_connect_time
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/2029f551e57f70f7.json.
Report an issue: GitHub.