redis/redis-py · error · ConnectionError
Connection closed by server.
Error message
Connection closed by server.
What it means
Raised by the sync RESP2 pure-Python parser when SocketBuffer.readline() returns empty — the server closed the connection before sending a complete reply line. It surfaces as redis.exceptions.ConnectionError so the caller reconnects.
Source
Thrown at redis/_parsers/resp2.py:34
pos = self._buffer.get_pos() if self._buffer else None
try:
result = self._read_response(
disable_decoding=disable_decoding, timeout=timeout
)
except BaseException:
if self._buffer:
self._buffer.rewind(pos)
raise
else:
self._buffer.purge()
return result
def _read_response(
self, disable_decoding=False, timeout: Union[float, object] = SENTINEL
):
raw = self._buffer.readline(timeout=timeout)
if not raw:
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
byte, response = raw[:1], raw[1:]
# server returned an error
if byte == b"-":
response = response.decode("utf-8", errors="replace")
error = self.parse_error(response)
# if the error is a ConnectionError, raise immediately so the user
# is notified
if isinstance(error, ConnectionError):
raise error
# otherwise, we're dealing with a ResponseError that might belong
# inside a pipeline response. the connection's read_response()
# and/or the pipeline's execute() will raise this error if
# necessary, so just return the exception instance here.
return error
# single value
elif byte == b"+":View on GitHub (pinned to 43bf5ac31a)
Solutions
- Enable health_check_interval and retry_on_error=[ConnectionError, TimeoutError].
- Set socket_keepalive=True.
- Tune Redis `timeout` to exceed your pool's idle window.
- Catch ConnectionError and retry on a fresh connection.
Example fix
# before
r = redis.Redis(host='redis')
r.get('k')
# after
r = redis.Redis(host='redis', health_check_interval=30,
socket_keepalive=True,
retry_on_error=[redis.ConnectionError, redis.TimeoutError])
r.get('k') Defensive patterns
Strategy: retry
Validate before calling
# Probe liveness before a critical command.
try:
assert r.ping()
except redis.ConnectionError:
r.close(); r = redis.Redis(...)
r.get('k') Type guard
def is_closed_error(exc: Exception) -> bool:
from redis.exceptions import ConnectionError
return isinstance(exc, ConnectionError) and 'closed by server' in str(exc) Try / catch
from redis.exceptions import ConnectionError
try:
return r.get('k')
except ConnectionError:
r = redis.Redis(...)
return r.get('k') Prevention
- Always set health_check_interval in production.
- Enable retry_on_error for transient network errors.
- Keep socket_keepalive on across NAT/LB hops.
When it happens
Trigger: Any sync command via the pure-Python RESP2 parser when the server half-closes the socket: restart, `timeout`, CLIENT KILL, failover, proxy idle drop, or a truncated/malformed reply that drains the buffer to EOF.
Common situations: Same family as other server-close errors — managed Redis/proxies reaping idle flows, rolling deploys, failover, maxmemory-clients eviction.
Understand the failure class
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
- Connection closed by server.
- Connection closed by server.
- Connection closed by server.
- Buffer is closed.
- Connection closed by server.
AI-assisted analysis of redis/redis-py@43bf5ac31a (2026-08-06).
Data as JSON: /api/errors/658bd2d41ab8aa10.
Report an issue: GitHub.