redis/redis-py · error · ConnectionError
Error {errno} while writing to socket. {errmsg}.
Error message
Error {errno} while writing to socket. {errmsg}. What it means
Raised as a ConnectionError in send_packed_command when an OSError (other than timeout) occurs during socket.sendall. The errno and message from the OS exception are embedded. The connection is disconnected before raising. This covers low-level socket failures like broken pipe, connection reset, etc.
Source
Thrown at redis/connection.py:1360
# guard against health check recursion
if check_health:
self.check_health()
try:
if isinstance(command, str):
command = [command]
for item in command:
self._sock.sendall(item)
except socket.timeout:
self.disconnect()
raise TimeoutError("Timeout writing to socket")
except OSError as e:
self.disconnect()
if len(e.args) == 1:
errno, errmsg = "UNKNOWN", e.args[0]
else:
errno = e.args[0]
errmsg = e.args[1]
raise ConnectionError(f"Error {errno} while writing to socket. {errmsg}.")
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.
self.disconnect()
raise
def send_command(self, *args, **kwargs):
"""Pack and send a command to the Redis server"""
self.send_packed_command(
self._command_packer.pack(*args),
check_health=kwargs.get("check_health", True),
)
def can_read(self, timeout: float = 0) -> bool:
"""Poll the socket to see if there's data that can be read."""
# TODO: Rename this API; it detects pending data or dirty/closedView on GitHub (pinned to da03cdc7e8)
Solutions
- Enable retry_on_error=[ConnectionError] (or rely on the pool to hand a fresh connection on the next call).
- Set health_check_interval to detect dead connections before issuing commands.
- Investigate the embedded errno: EPIPE/ECONNRESET indicate the peer closed the connection.
- Stabilize the network path or increase keepalive to prevent idle drops.
Example fix
// before
r = redis.Redis(host=h)
// after
from redis.retry import Retry
from redis.backoff import ExponentialWithJitterBackoff
r = redis.Redis(host=h, retry_on_error=[redis.ConnectionError],
retry=Retry(ExponentialWithJitterBackoff(), 3)) Defensive patterns
Strategy: retry
Try / catch
try:
r.set('k', 'v')
except redis.exceptions.ConnectionError as e:
if 'while writing to socket' in str(e):
# peer dropped connection; pool yields a fresh one on retry
r.set('k', 'v') Prevention
- Set retry_on_error=[ConnectionError] and health_check_interval.
- Investigate the embedded errno (EPIPE/ECONNRESET) for the root cause.
- Use TCP keepalive to prevent idle NAT drops.
When it happens
Trigger: Any OSError during write: the peer closed the socket (EPIPE / broken pipe), a reset (ECONNRESET), or the local socket was invalidated. Happens mid-command when the server or a network device drops the TCP connection.
Common situations: Server restart/crash dropping connections; firewall/NAT idle-timeout killing the connection; a proxy recycling the upstream; client and server on different networks with intermittent connectivity; forked process using a socket from the parent.
Related errors
- Error {err_no} while writing to socket. {errmsg}.
- Timeout writing to socket
- Error while reading from {host_error} : {e.args}
- Timeout writing to socket
- Error while reading from {host_error} : {e.args}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/39000fb6bec459e0.json.
Report an issue: GitHub.