-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
This might be related to #2893 (Sentinel recursion), but it also happens in non-Sentinel setups
Bug Description
redis.asyncio enters infinite recursion when retry_on_timeout=True or health_check_interval>0 are set.
Environment
Python: 3.11.x, 3.12.x (both affected)
redis-py: 5.0.1 (also tested with 4.6.0)
Parser: default (no hiredis)
OS: Docker (python:3.12-slim-bookworm)
uvloop: disabled
Minimal Reproduction
import asyncio
import redis.asyncio as redis
async def reproduce():
client = redis.from_url(
"redis://default:password@localhost:6379/0",
retry_on_timeout=True,
health_check_interval=30,
)
await client.ping() # RecursionError
asyncio.run(reproduce())
Working Configuration
client = redis.from_url(
"redis://default:password@localhost:6379/0",
retry_on_timeout=False,
health_check_interval=0,
)
Stack Trace Pattern
RecursionError: maximum recursion depth exceeded
connect() → on_connect() → send_command("CLIENT SETINFO")
→ check_health() → _send_ping() → send_command("PING")
→ back to connect() (infinite loop)
Key Findings
Trigger: enabling retry or health check during initial connection.
Not Python-version-specific, reproducible on 3.11 and 3.12.
Not parser-specific (occurs with PythonParser too).
Root cause: circular dependency between connection setup and health check.
Workaround
Disable retry and health check:
redis.from_url(..., retry_on_timeout=False, health_check_interval=0)
Expected Behavior
Health checks and retries should not trigger recursion during connection initialization.