apache/kafka · error · IllegalArgumentException

Timeout needs to be greater than 0

Error message

Timeout needs to be greater than 0

What it means

Thrown by NetworkClientUtils.awaitReady() when timeoutMs is negative. Note the message says 'greater than 0' but the guard is timeoutMs < 0, so a value of exactly 0 is permitted. This is a pre-condition check on the supplied timeout before entering the connection-wait loop.

Solutions

  1. Ensure the timeoutMs passed to awaitReady is >= 0; clamp negative computed values to 0.
  2. Check deadline arithmetic: compute remaining as max(0, deadline - now) to avoid underflow.
  3. Validate configuration values for timeout properties are non-negative.

Example fix

// before
long remaining = deadline - time.milliseconds();
awaitReady(client, node, time, remaining); // may be negative

// after
long remaining = Math.max(0, deadline - time.milliseconds());
awaitReady(client, node, time, remaining);
Defensive patterns

Strategy: validation

Validate before calling

long timeoutMs = Math.max(0, deadline - time.milliseconds());
NetworkClientUtils.awaitReady(client, node, time, timeoutMs);

Prevention

When it happens

Trigger: Calling awaitReady(client, node, time, timeoutMs) with a negative timeoutMs value. This typically comes from arithmetic that underflows or a misconfigured timeout setting.

Common situations: Deadline calculations that subtract too much elapsed time and go negative, misconfigured request.timeout.ms or related timeout properties, or programmatic callers computing remaining time incorrectly.

Understand the failure class

Related errors


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/1954cf205a5144ae. Report an issue: GitHub.

Appendix: source

Thrown at clients/src/main/java/org/apache/kafka/clients/NetworkClientUtils.java:61

        client.poll(0, currentTime);
        return client.isReady(node, currentTime);
    }

    /**
     * Invokes `client.poll` to discard pending disconnects, followed by `client.ready` and 0 or more `client.poll`
     * invocations until the connection to `node` is ready, the timeoutMs expires or the connection fails.
     *
     * It returns `true` if the call completes normally or `false` if the timeoutMs expires. If the connection fails,
     * an `IOException` is thrown instead. Note that if the `NetworkClient` has been configured with a positive
     * connection timeoutMs, it is possible for this method to raise an `IOException` for a previous connection which
     * has recently disconnected. If authentication to the node fails, an `AuthenticationException` is thrown.
     *
     * This method is useful for implementing blocking behaviour on top of the non-blocking `NetworkClient`, use it with
     * care.
     */
    public static boolean awaitReady(KafkaClient client, Node node, Time time, long timeoutMs) throws IOException {
        if (timeoutMs < 0) {
            throw new IllegalArgumentException("Timeout needs to be greater than 0");
        }
        long startTime = time.milliseconds();

        if (isReady(client, node, startTime) ||  client.ready(node, startTime))
            return true;

        long attemptStartTime = time.milliseconds();
        while (!client.isReady(node, attemptStartTime) && attemptStartTime - startTime < timeoutMs) {
            if (client.connectionFailed(node)) {
                throw new IOException("Connection to " + node + " failed.");
            }
            long pollTimeout = timeoutMs - (attemptStartTime - startTime); // initialize in this order to avoid overflow

            // If the network client is waiting to send data for some reason (eg. throttling or retry backoff),
            // polling longer than that is potentially dangerous as the producer will not attempt to send
            // any pending requests.
            long waitingTime = client.pollDelayMs(node, startTime);
            if (waitingTime > 0 && pollTimeout > waitingTime) {

View on GitHub (pinned to 996fb4585a)