apache/kafka · error · TimeoutException

Timeout of {}ms expired before successfully committing offse

Error message

Timeout of {}ms expired before successfully committing offsets {}

What it means

Thrown as TimeoutException from commitSync when coordinator.commitOffsetsSync returns false, meaning the default-api-timeout or the explicitly passed Duration elapsed before the broker acknowledged the OffsetCommit. It signals the offset commit did not complete within the user-supplied budget; offsets were not durably committed and at-least-once consumption risk remains.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java:762

    @Override
    public void commitSync(Duration timeout) {
        commitSync(subscriptions.allConsumed(), timeout);
    }

    @Override
    public void commitSync(final Map<TopicPartition, OffsetAndMetadata> offsets) {
        commitSync(offsets, Duration.ofMillis(defaultApiTimeoutMs));
    }

    @Override
    public void commitSync(final Map<TopicPartition, OffsetAndMetadata> offsets, final Duration timeout) {
        acquireAndEnsureOpen();
        long commitStart = time.nanoseconds();
        try {
            throwIfGroupIdNotDefined();
            offsets.forEach(this::updateLastSeenEpochIfNewer);
            if (!coordinator.commitOffsetsSync(new HashMap<>(offsets), time.timer(timeout))) {
                throw new TimeoutException("Timeout of " + timeout.toMillis() + "ms expired before successfully " +
                        "committing offsets " + offsets);
            }
        } finally {
            kafkaConsumerMetrics.recordCommitSync(time.nanoseconds() - commitStart);
            release();
        }
    }

    @Override
    public void commitAsync() {
        commitAsync(null);
    }

    @Override
    public void commitAsync(OffsetCommitCallback callback) {
        commitAsync(subscriptions.allConsumed(), callback);
    }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Increase the timeout passed to commitSync (or raise default.api.timeout.ms / request.timeout.ms) to accommodate broker latency.
  2. Investigate broker/group-coordinator health, GC, and network latency; commit timeouts are usually a symptom, not the root cause.
  3. Switch to commitAsync for non-critical commits, or retry commitSync with backoff inside an application-level loop while handling WakeupException.
  4. Reduce the size of the offsets map being committed and ensure no rebalance is in flight (consider adjusting max.poll.interval-ms).

Example fix

// before
consumer.commitSync(offsets, Duration.ofMillis(5000)); // frequently times out

// after
consumer.commitSync(offsets, Duration.ofMillis(60000)); // or rely on default.api.timeout.ms
// plus: tune max.poll.interval.ms, session.timeout.ms; check broker/coordinator health
Defensive patterns

Strategy: retry

Validate before calling

// Choose a timeout larger than the broker's default; check group coordinator reachability first
long commitTimeoutMs = Math.max(
    (long) consumerProps.getOrDefault("default.api.timeout.ms", 60000),
    requestTimeoutMs * 3);
consumer.commitSync(offsets, java.time.Duration.ofMillis(commitTimeoutMs));

Type guard

// Validate offsets are well-formed and within log bounds before committing
static boolean offsetsCommittable(java.util.Map<org.apache.kafka.common.TopicPartition, org.apache.kafka.clients.consumer.OffsetAndMetadata> offsets) {
    return offsets.entrySet().stream().allMatch(e ->
        e.getKey() != null && e.getValue() != null && e.getValue().offset() >= 0);
}

Try / catch

int maxAttempts = 3;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
        consumer.commitSync(offsets, java.time.Duration.ofMillis(timeoutMs));
        break;
    } catch (org.apache.kafka.common.errors.TimeoutException e) {
        if (attempt == maxAttempts) throw e;
        // backoff before retry; the broker may recover
        Thread.sleep(backoffMs * attempt);
    }
}

Prevention

When it happens

Trigger: Calling commitSync(offsets, Duration.ofMillis(N)) with N too small for the broker round-trip. Broker unavailable or slow, group coordinator reassigning, network partition, consumer rebalance in progress, or the request queue backed up. Default api.timeout.ms too low for the deployment.

Common situations: Production environment with broker GC pauses or controller failover. Cross-AZ/region latency pushing commit beyond default 60s. Committing a large offsets map during a rebalance. Tight timeout chosen to fail fast without considering broker response time.

Related errors


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