redis/redis-py · error · ConnectionError
Bad response from PING health check
Error message
Bad response from PING health check
What it means
Raised as a ConnectionError by _send_ping during a health check when the PING command's response is not 'PONG'. The socket is alive but the server returned an unexpected/garbled reply, indicating protocol corruption or a misbehaving intermediary. Health checks run periodically when health_check_interval is set.
Source
Thrown at redis/connection.py:1321
self.maintenance_state = MaintenanceState.NONE
# reset the sets that keep track of received start maint
# notifications and skipped end maint notifications
self.reset_received_notifications()
def mark_for_reconnect(self):
self._should_reconnect = True
def should_reconnect(self):
return self._should_reconnect
def reset_should_reconnect(self):
self._should_reconnect = False
def _send_ping(self):
"""Send PING, expect PONG in return"""
self.send_command("PING", check_health=False)
if str_if_bytes(self.read_response()) != "PONG":
raise ConnectionError("Bad response from PING health check")
def _ping_failed(self, error, failure_count):
"""Function to call when PING fails"""
self.disconnect(
error=error, failure_count=failure_count, health_check_failed=True
)
def check_health(self):
"""Check the health of the connection with a PING/PONG"""
if self.health_check_interval and time.monotonic() > self.next_health_check:
self.retry.call_with_retry(
self._send_ping,
self._ping_failed,
with_failure_count=True,
)
def send_packed_command(self, command, check_health=True):
"""Send an already packed command to the Redis server"""View on GitHub (pinned to da03cdc7e8)
Solutions
- Let the connection be discarded and retried (the client disconnects on this error).
- Investigate any proxy/LB between client and server for non-Redis responses.
- Reduce connection-pool reuse issues by lowering socket_timeout / health_check_interval.
- Check server logs for OOM or protocol-level problems.
Example fix
// before r = redis.Redis(host=h, health_check_interval=120) // after r = redis.Redis(host=h, health_check_interval=30) # detect bad sockets sooner
Defensive patterns
Strategy: retry
Try / catch
try:
r.set('k', 'v')
except redis.exceptions.ConnectionError as e:
if 'PING health check' in str(e):
# poisoned socket discarded; retry on a fresh connection
r.set('k', 'v') Prevention
- Set a reasonable health_check_interval to evict bad sockets early.
- Investigate proxies/LBs that may inject non-Redis bytes.
- Avoid reusing connections across forked processes.
When it happens
Trigger: The periodic check_health() (gated by health_check_interval) calls _send_ping; if read_response() yields anything other than 'PONG', this fires. Common with a proxy returning an HTML error page, a connection pool handing back a poisoned/corrupted socket, or a RESP parsing desync.
Common situations: A misbehaving proxy/load balancer injecting non-Redis bytes; RESP parser desync after a malformed response; socket reused from a pool in a bad state; server under extreme memory pressure returning OOM-style replies on PING.
Related errors
- Bad response from PING health check
- A non health check response was cleaned by execute_command:
- Connection closed by server.
- Buffer is closed.
- Connection closed by server.
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/c338869636befef1.json.
Report an issue: GitHub.