pika/pika · error · ValueError
timeout must >= 1, but got {timeout!r}
Error message
timeout must >= 1, but got {timeout!r} What it means
HeartbeatChecker.__init__ (heartbeat.py:37-38) requires its timeout argument to be at least 1; anything smaller raises ValueError. The value drives both the heartbeat send interval (timeout/2) and the stale-connection check interval (timeout+5), so a zero or fractional timeout would produce a zero or negative send interval and break the scheduler. The check is a hard floor, not a recommendation.
Source
Thrown at pika/heartbeat.py:38
_STALE_CONNECTION = 'No activity or too many missed heartbeats in the last %i seconds'
def __init__(self, connection, timeout) -> None:
"""
Create an object that will check for activity on the provided connection as well as receive
heartbeat frames from the broker. The timeout parameter defines a window within which this
activity must happen. If not, the connection is considered dead and closed.
The value must be >= 1. The value passed for timeout is also used to calculate an interval
at which a heartbeat frame is sent to the broker. The interval is equal to the timeout value
divided by two.
:param connection: Connection object
:param timeout: Connection idle timeout. If no activity occurs on the connection nor
heartbeat frames received during the timeout window the connection will be closed. The
interval used to send heartbeats is calculated from this value by dividing it by two.
"""
if timeout < 1:
raise ValueError(f'timeout must >= 1, but got {timeout!r}')
self._connection = connection
# Note: see the following documents:
# https://www.rabbitmq.com/heartbeats.html#heartbeats-timeout
# https://github.com/pika/pika/pull/1072
# https://groups.google.com/d/topic/rabbitmq-users/Fmfeqe5ocTY/discussion
# There is a certain amount of confusion around how client developers
# interpret the spec. The spec talks about 2 missed heartbeats as a
# *timeout*, plus that any activity on the connection counts for a
# heartbeat. This is to avoid edge cases and not to depend on network
# latency.
self._timeout = timeout
self._send_interval = float(timeout) / 2
# Note: Pika will calculate the heartbeat / connectivity check interval
# by adding 5 seconds to the negotiated timeout to leave a bit of roomView on GitHub (pinned to 295ad9e579)
Solutions
- Ensure the heartbeat value passed is an integer >= 1 (use 0 only to disable, and let Connection._create_heartbeat_checker skip construction).
- If you need to disable heartbeats, set ConnectionParameters(heartbeat=0) rather than building a HeartbeatChecker manually.
- When using a heartbeat callback, clamp the return to max(1, desired) and return an int.
Example fix
# before checker = pika.heartbeat.HeartbeatChecker(conn, 0) # after params = pika.ConnectionParameters(heartbeat=0) # disables heartbeat entirely
Defensive patterns
Strategy: validation
Validate before calling
if isinstance(params.heartbeat, int) and params.heartbeat < 1:
# 0 disables; any other sub-1 int is invalid
params.heartbeat = 0 if params.heartbeat == 0 else 1
# or, for a custom checker:
timeout = max(1, int(timeout)) if timeout else 0
if timeout:
checker = pika.heartbeat.HeartbeatChecker(conn, timeout) Type guard
def is_valid_heartbeat_timeout(v: int) -> bool:
return isinstance(v, int) and v >= 1 Try / catch
try:
checker = pika.heartbeat.HeartbeatChecker(conn, timeout)
except ValueError:
timeout = 60
checker = pika.heartbeat.HeartbeatChecker(conn, timeout) Prevention
- Let ConnectionParameters manage heartbeat; do not construct HeartbeatChecker yourself unless you are writing an adapter.
- Treat 0 as 'disable' everywhere, and keep all other values >= 1.
When it happens
Trigger: Negotiating a heartbeat of 0 with the broker would normally disable the checker (_create_heartbeat_checker guards with heartbeat > 0), but this error surfaces if HeartbeatChecker is constructed directly with a value < 1, or if a custom heartbeat callback returns 0 or a fractional value that bypasses the int/positivity guard at line 1671. Constructing pika.heartbeat.HeartbeatChecker(conn, 0) reproduces it.
Common situations: Directly instantiating HeartbeatChecker in tests or custom adapters with a 0 or negative timeout; a heartbeat negotiation callback returning a float < 1; manually setting params.heartbeat to a sub-1 value after tune.
Related errors
- blocked_connection_timeout must be >= 0, but got {value!r}
- connection_attempts must be > 0, but got {value!r}
- Invalid socket_timeout value {value!r}: {exc!r}
- Invalid stack_timeout value {value!r}: {exc!r}
- Specified ssl_options=None URI arg is inconsistent with the
AI-assisted analysis of pika/pika@295ad9e579 (2026-08-04).
Data as JSON: /data/errors/913b9b47a5ecd9de.json.
Report an issue: GitHub.