apache/kafka · error · org.apache.kafka.common.errors.TimeoutException

Operation timed out before completion

Error message

Operation timed out before completion

What it means

Thrown by AsyncKafkaConsumer.processBackgroundEvents as a TimeoutException when the overall timer expires before the enqueued background event completes its CompletableFuture. The async consumer drives work on a background network thread and the application thread polls for completion; if the broker, coordinator, or callback chain does not finish within the operation's deadline (default.api.timeout.ms or the request-specific timer), this generic timeout fires. The message is intentionally generic because the same loop backs poll(), commitSync, position(), unsubscribe and other blocking calls.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java:2479

                    // If the event is done (either successfully or otherwise), go ahead and attempt to return
                    // without waiting. We use the ConsumerUtils.getResult() method here to handle the conversion
                    // of the exception types.
                    return ConsumerUtils.getResult(future);
                } else if (!hadEvents) {
                    // If the above processing yielded no events, then let's sit tight for a bit to allow the
                    // background thread to either finish the task, or populate the background event
                    // queue with things to process in our next loop.
                    Timer pollInterval = time.timer(100L);
                    return ConsumerUtils.getResult(future, pollInterval);
                }
            } catch (TimeoutException swallow) {
                // Ignore this as we will retry the event until the timeout expires.
            } finally {
                timer.update();
            }
        } while (timer.notExpired());

        throw new TimeoutException("Operation timed out before completion");
    }

    static ConsumerRebalanceListenerCallbackCompletedEvent invokeRebalanceCallbacks(ConsumerRebalanceListenerInvoker rebalanceListenerInvoker,
                                                                                    ConsumerRebalanceListenerMethodName methodName,
                                                                                    SortedSet<TopicPartition> partitions,
                                                                                    CompletableFuture<Void> future) {
        Exception e;

        try {
            switch (methodName) {
                case ON_PARTITIONS_REVOKED:
                    e = rebalanceListenerInvoker.invokePartitionsRevoked(partitions);
                    break;

                case ON_PARTITIONS_ASSIGNED:
                    e = rebalanceListenerInvoker.invokePartitionsAssigned(partitions);
                    break;

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Increase default.api.timeout.ms and/or request.timeout.ms to values that match your cluster's observed latency, and verify the broker is healthy.
  2. Inspect the consumer logs for the underlying cause: TimeoutException here is a wrapper; look for the preceding RebalanceInProgressException, NotCoordinatorException, or callback exceptions in the same trace.
  3. Ensure any ConsumerRebalanceListener callbacks return quickly (no blocking I/O); offload slow work to a separate thread and only touch consumer state from the callback thread.
  4. Tune retry.backoff.ms / retry.backoff.max.ms so transient coordinator movement recovers within the deadline.
  5. If the issue is during rebalance, check max.poll.interval.ms versus your record-processing time and lower batch size or raise the interval.

Example fix

// before
props.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 10000);
consumer.commitSync(); // throws TimeoutException on slow cluster

// after
props.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 60000);
props.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, 30000);
consumer.commitSync();
Defensive patterns

Strategy: retry

Validate before calling

// No pre-validation prevents a runtime timeout, but you can pre-size timeouts.
Properties p = new Properties();
p.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 60000); // default ~60s
p.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, 30000);
p.put(ConsumerConfig.RETRY_BACKOFF_MS_CONFIG, 500);
p.put(ConsumerConfig.RETRY_BACKOFF_MAX_MS_CONFIG, 10000);

Try / catch

// Retry with bounded attempts + exponential backoff for TimeoutException.
int attempts = 0, maxAttempts = 3;
while (true) {
    try {
        return consumer.position(partition); // or whichever op timed out
    } catch (TimeoutException e) {
        if (++attempts > maxAttempts) throw e;
        long backoff = Math.min(1000L * (1L << attempts), 8000L);
        Thread.sleep(backoff);
    }
}

Prevention

When it happens

Trigger: Any blocking call on the async consumer whose Future does not complete within the timer: commitSync() exceeding default.api.timeout.ms; poll() against an unavailable broker or during a long rebalance; unsubscribe() that cannot finish because a ConsumerRebalanceListener.onPartitionsRevoked callback on the application thread is itself blocking; position(partition) when offset fetch is slow.

Common situations: Broker outage or network partition making the coordinator unreachable; max.poll.interval.ms exceeded so the consumer was kicked out of the group mid-operation; a user-supplied ConsumerRebalanceListener that blocks (DB locks, slow HTTP) and stalls the handoff between background and application threads; default.api.timeout.ms set too low for a slow cluster; GC pauses or overloaded hosts stretching coordinator responses past the deadline.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/c5834398c437c2c5.json. Report an issue: GitHub.