locustio/locust · error · ValueError
Invalid timeout.
Error message
Invalid timeout.
What it means
The MQTT client's selector-based network loop (_loop_selectors) raises ValueError when the given timeout is negative, since selectors cannot wait for a negative duration. This is a defensive check inside the custom gevent-compatible loop of locust's MQTT contrib client.
Source
Thrown at locust/contrib/mqtt.py:345
reasoncode: ReasonCode,
properties: Properties | None,
) -> None:
self._on_connect_cb(client, userdata, {}, reasoncode)
def _loop(self, timeout: float = 1.0) -> MQTTErrorCode:
"""Override the parent's _loop method to optionally use selectors.
When use_loop_selectors is True, this uses a selector-based implementation that allows more than 340 connections.
Otherwise, it falls back to the parent's implementation.
"""
if self._use_loop_selectors:
return self._loop_selectors(timeout)
else:
return super()._loop(timeout)
def _loop_selectors(self, timeout: float = 1.0) -> MQTTErrorCode:
if timeout < 0.0:
raise ValueError("Invalid timeout.")
sel = selectors.DefaultSelector()
eventmask = selectors.EVENT_READ
with suppress(IndexError):
packet = self._out_packet.popleft()
self._out_packet.appendleft(packet)
eventmask = selectors.EVENT_WRITE | eventmask
# used to check if there are any bytes left in the (SSL) socket
pending_bytes = 0
if hasattr(self._sock, "pending"):
pending_bytes = self._sock.pending() # type: ignore
# if bytes are pending do not wait in select
if pending_bytes > 0:
timeout = 0.0View on GitHub (pinned to f391a716e1)
Solutions
- Ensure the timeout value passed into the loop is >= 0.0
- Clamp the computed timeout: timeout = max(0.0, timeout)
- Check keepalive/timeout settings on the MQTT client configuration
Example fix
// before client.loop(timeout=computed_deadline - now) # may be negative // after timeout = max(0.0, computed_deadline - now) client.loop(timeout=timeout)
Defensive patterns
Strategy: validation
Validate before calling
timeout = max(0.0, timeout)
assert timeout >= 0.0, f"MQTT loop timeout must be non-negative, got {timeout}" Prevention
- Clamp computed timeouts to >= 0 before passing to the loop
- Avoid passing absolute deadlines where relative durations are expected
- Test MQTT users with short runs to surface loop configuration errors early
When it happens
Trigger: Constructing or configuring the MQTT user/client such that the loop timeout resolves below 0.0 (e.g. keepalive or timeout math yielding a negative value) while the selectors-based loop path is active.
Common situations: Custom timeout configuration in a Milvus/MQTT locustfile; clock/deadline calculations passing past deadlines as negative timeouts; subclass overriding _loop and passing a bad timeout.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- 'uri' must be provided for MilvusUser
- 'collection_name' must be provided for MilvusUser
- Ground truth length is less than limit: {len(ground_truth)}
- You need to set OPENAI_API_KEY env var to use OpenAIUser
- No tasks defined on {self.__class__.__name__}{extra_message}
AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29).
Data as JSON: /api/errors/f86214725a354ce7.
Report an issue: GitHub.