redis/redis-py · error · PubSubError
A non health check response was cleaned by execute_command:
Error message
A non health check response was cleaned by execute_command: {response} What it means
Raised in `PubSub.clean_health_check_responses` while draining queued health-check PING replies. The client periodically sends `PING <health-check-message>` to keep the pubsub socket alive; when it later drains those replies it expects every consumed frame to be the matching health-check response. If a frame is consumed that is NOT a health-check reply, a `PubSubError` is raised because the socket's framing has desynchronized and continuing would corrupt the message stream.
Source
Thrown at redis/client.py:1247
kwargs = {"check_health": not self.subscribed}
if not self.subscribed:
self.clean_health_check_responses()
with self._lock:
self._execute(connection, connection.send_command, *args, **kwargs)
def clean_health_check_responses(self) -> None:
"""
If any health check responses are present, clean them
"""
ttl = 10
conn = self.connection
while conn and self.health_check_response_counter > 0 and ttl > 0:
if self._execute(conn, conn.can_read, timeout=conn.socket_timeout):
response = self._execute(conn, conn.read_response)
if self.is_health_check_response(response):
self.health_check_response_counter -= 1
else:
raise PubSubError(
"A non health check response was cleaned by "
"execute_command: {}".format(response)
)
ttl -= 1
def _reconnect(
self,
conn,
error: Optional[Exception] = None,
failure_count: Optional[int] = None,
start_time: Optional[float] = None,
command_name: Optional[str] = None,
) -> None:
"""
The supported exceptions are already checked in the
retry object so we don't need to do it here.
In this error handler we are trying to reconnect to the server.View on GitHub (pinned to da03cdc7e8)
Solutions
- Ensure the PubSub connection is used exclusively for pubsub (never share it with normal command traffic) — call `pubsub = client.pubsub()` and only use pubsub methods on it.
- If using RESP3, configure a proper push handler (`push_handler_func`) so push notifications are routed correctly and do not sit on the response stream.
- Recreate the PubSub object and re-subscribe after the error — the connection state is corrupted and cannot be recovered in place.
- Review `health_check_interval` and `socket_timeout`; if health checks fire faster than the consumer drains them, raise the interval or ensure `get_message()` is polled frequently.
Example fix
# before
ps = client.pubsub()
ps.subscribe('ch')
# same client used elsewhere -> interleaved traffic
# after
ps = client.pubsub()
ps.subscribe('ch')
for msg in ps.listen():
handle(msg) # drain promptly, keep this connection pubsub-only Defensive patterns
Strategy: try-catch
Try / catch
from redis.exceptions import PubSubError
try:
msg = ps.get_message(timeout=1.0)
except PubSubError:
# connection framing is corrupted — recreate pubsub and re-subscribe
ps.close()
ps = client.pubsub()
ps.subscribe('ch') Prevention
- Dedicate the pubsub connection to pubsub only — never run normal commands on it.
- In RESP3, configure a push_handler_func so push frames do not sit on the response stream.
- Poll get_message frequently so health-check replies are drained promptly.
When it happens
Trigger: A PubSub instance with `health_check_interval` configured loses ordering between the health-check PING and other pubsub traffic — typically because the connection was shared or reused, a server-pushed message arrived interleaved with the PING reply, the connection dropped and reconnected mid-drain, or a RESP3 push notification was mistaken for a reply. The loop (ttl=10) drains up to 10 frames and raises on the first non-health-check frame.
Common situations: Long-lived pubsub listeners on unstable networks where reconnects race with health checks; RESP3 mode with push handlers enabled; mixed usage of the same connection for pubsub and normal commands; version changes that altered push/health-check framing.
Related errors
- Buffer is closed.
- Connection closed by server.
- Maintenance notifications are only supported with hiredis an
- Bad response from PING health check
- Maintenance notifications are only supported with hiredis an
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/03998d9e4dd1fccc.json.
Report an issue: GitHub.