{"record":{"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/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/connection.py#L1183-L1219","documentation":"Raised as ConnectionError from send_packed_command() when the underlying writer raises OSError (anything other than asyncio.TimeoutError). The library extracts errno + errmsg (defaulting err_no to 'UNKNOWN' if there is only one arg), disconnects nowait, and re-raises wrapped. Typical causes are broken-pipe, connection-reset, or EAGAIN on a dead socket.","triggerScenarios":"Any command sent on a connection whose TCP peer has closed/reset: server crash, failover, idle timeout evicting the connection, NAT reaping, or a proxy dropping the session. The first command after such an event surfaces here.","commonSituations":"Idle connection killed by a cloud LB (typical AWS ElastiCache idle timeout 60-300s); Redis failover to a replica; network partition; forked process sharing sockets; TLS session torn down remotely.","solutions":["Enable retry with RetryOnDisconnect or a backoff policy so transient resets are retried automatically.","Lower the connection pool idle eviction and/or the server timeout so stale connections are pruned before reuse.","Enable socket_keepalive so dead connections are detected proactively.","Investigate failover/network stability if the errors are persistent rather than occasional."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h)\n// after\nfrom redis.retry import Retry\nfrom redis.backoff import ExponentialBackoff\nr = redis.asyncio.Redis(host=h, retry=Retry(ExponentialBackoff(), 3), retry_on_error=[ConnectionError], socket_keepalive=True)","handlingStrategy":"retry","validationCode":"null","typeGuard":"from redis.exceptions import ConnectionError\n\ndef is_socket_write_error(exc: BaseException) -> bool:\n    return isinstance(exc, ConnectionError) and 'writing to socket' in str(exc).lower()","tryCatchPattern":"from redis.retry import Retry\nfrom redis.backoff import ExponentialBackoff\nfrom redis.exceptions import ConnectionError\n\nr = redis.asyncio.Redis(\n    host=h,\n    retry=Retry(ExponentialBackoff(), 3),\n    retry_on_error=[ConnectionError],\n    socket_keepalive=True,\n)","preventionTips":["Enable retry_on_error=[ConnectionError] for idempotent commands.","Prune idle connections faster than the LB idle timeout.","Enable socket_keepalive."],"tags":["network","oserror","write","broken-pipe","connection-reset","async","retry"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}