redis/redis-py · error · ValueError

health_check_probes must be greater than 0

Error message

health_check_probes must be greater than 0

What it means

Raised by AbstractHealthCheck.__init__ (redis/asyncio/multidb/healthcheck.py:357) when the health_check_probes argument is less than 1. The multidb health-check subsystem needs at least one probe attempt to determine database liveness, so zero/negative is rejected at construction time before any check runs.

Source

Thrown at redis/asyncio/multidb/healthcheck.py:357

class HealthCheckPolicies(Enum):
    HEALTHY_ALL = HealthyAllPolicy
    HEALTHY_MAJORITY = HealthyMajorityPolicy
    HEALTHY_ANY = HealthyAnyPolicy


DEFAULT_HEALTH_CHECK_POLICY: HealthCheckPolicies = HealthCheckPolicies.HEALTHY_ALL


class AbstractHealthCheck(HealthCheck):
    def __init__(
        self,
        health_check_probes: int = DEFAULT_HEALTH_CHECK_PROBES,
        health_check_delay: float = DEFAULT_HEALTH_CHECK_DELAY,
        health_check_timeout: float = DEFAULT_HEALTH_CHECK_TIMEOUT,
    ):
        if health_check_probes < 1:
            raise ValueError("health_check_probes must be greater than 0")
        self._health_check_probes = health_check_probes
        self._health_check_delay = health_check_delay
        self._health_check_timeout = health_check_timeout

    @property
    def health_check_probes(self) -> int:
        return self._health_check_probes

    @property
    def health_check_delay(self) -> float:
        return self._health_check_delay

    @property
    def health_check_timeout(self) -> float:
        return self._health_check_timeout

    @abstractmethod
    async def check_health(self, database, hc_client: AsyncRedisClientT) -> bool:

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Set health_check_probes to a positive integer (the DEFAULT_HEALTH_CHECK_PROBES constant is the intended default).
  2. If you meant to disable health checks, do not construct a health-check object at all; instead omit the policy / use a no-op health strategy.
  3. Validate the config value (int(v) > 0) before passing it into the health-check constructor.

Example fix

// before
hc = PingHealthCheck(health_check_probes=0)
// after
hc = PingHealthCheck(health_check_probes=DEFAULT_HEALTH_CHECK_PROBES)
Defensive patterns

Strategy: validation

Validate before calling

from redis.asyncio.multidb.healthcheck import DEFAULT_HEALTH_CHECK_PROBES
if not isinstance(probes, int) or probes < 1:
    probes = DEFAULT_HEALTH_CHECK_PROBES
hc = PingHealthCheck(health_check_probes=probes)

Type guard

def is_valid_probe_count(v) -> bool:
    return isinstance(v, int) and v >= 1

Try / catch

try:
    hc = PingHealthCheck(health_check_probes=probes)
except ValueError as e:
    raise SystemConfigError(f"bad health_check_probes: {e}") from e

Prevention

When it happens

Trigger: Instantiating PingHealthCheck, LagAwareHealthCheck, or any AbstractHealthCheck subclass with health_check_probes=0 or a negative value; passing a probes count sourced from an empty/zeroed config value into the DatabaseConfig/health-check construction.

Common situations: Reading probe count from an environment variable or YAML config that defaults to 0; copying a config block and zeroing the probes field to "disable" probing (the API has no disable-by-zero semantics); arithmetic that underflows to 0.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/d04f2935d71f0dd4.json. Report an issue: GitHub.