{"id":"2029f551e57f70f7","repo":"redis/redis-py","slug":"error-err-no-while-writing-to-socket-errmsg","errorCode":null,"errorMessage":"Error {err_no} while writing to socket. {errmsg}.","messagePattern":"Error (.+?) while writing to socket\\. (.+?)\\.","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":1201,"sourceCode":"                command = [command]\n            if self.socket_timeout:\n                await asyncio.wait_for(\n                    self._send_packed_command(command), self.socket_timeout\n                )\n            else:\n                self._writer.writelines(command)\n                await self._writer.drain()\n        except asyncio.TimeoutError:\n            await self.disconnect(nowait=True)\n            raise TimeoutError(\"Timeout writing to socket\") from None\n        except OSError as e:\n            await self.disconnect(nowait=True)\n            if len(e.args) == 1:\n                err_no, errmsg = \"UNKNOWN\", e.args[0]\n            else:\n                err_no = e.args[0]\n                errmsg = e.args[1]\n            raise ConnectionError(\n                f\"Error {err_no} while writing to socket. {errmsg}.\"\n            ) from e\n        except BaseException:\n            # BaseExceptions can be raised when a socket send operation is not\n            # finished, e.g. due to a timeout.  Ideally, a caller could then re-try\n            # to send un-sent data. However, the send_packed_command() API\n            # does not support it so there is no point in keeping the connection open.\n            await self.disconnect(nowait=True)\n            raise\n\n    async def send_command(self, *args: Any, **kwargs: Any) -> None:\n        \"\"\"Pack and send a command to the Redis server\"\"\"\n        await self.send_packed_command(\n            self.pack_command(*args), check_health=kwargs.get(\"check_health\", True)\n        )\n\n    @deprecated_function(\n        version=\"8.0.0\", reason=\"Use can_read() instead\", name=\"can_read_destructive\"","sourceCodeStart":1183,"sourceCodeEnd":1219,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L1183-L1219","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h, port=p)\n\n// after\nfrom redis.backoff import ExponentialWithJitterBackoff\nfrom redis.retry import Retry\nretry = Retry(ExponentialWithJitterBackoff(), 3)\nr = redis.asyncio.Redis(host=h, port=p, retry=retry, retry_on_error=[ConnectionError])","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError\nfor attempt in range(3):\n    try:\n        await r.set(\"k\", \"v\")\n        break\n    except ConnectionError as e:\n        if \"while writing to socket\" in str(e):\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Configure retry_on_error=[ConnectionError] with backoff.","Enable socket_keepalive and health_check_interval.","Watch for firewall idle-timeout RSTs."],"tags":["network","write","connection-reset","broken-pipe","async"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}