{"id":"33de6e088f1ee6ff","repo":"apache/kafka","slug":"timeout-of-ms-expired-before-the-last-committed-33de6e","errorCode":null,"errorMessage":"Timeout of {}ms expired before the last committed offset for partitions {} could be determined. Try tuning {} larger to relax the threshold.","messagePattern":"Timeout of (.+?)ms expired before the last committed offset for partitions (.+?) could be determined\\. Try tuning (.+?) larger to relax the threshold\\.","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java","lineNumber":910,"sourceCode":"            release();\n        }\n    }\n\n    @Override\n    public Map<TopicPartition, OffsetAndMetadata> committed(final Set<TopicPartition> partitions) {\n        return committed(partitions, Duration.ofMillis(defaultApiTimeoutMs));\n    }\n\n    @Override\n    public Map<TopicPartition, OffsetAndMetadata> committed(final Set<TopicPartition> partitions, final Duration timeout) {\n        acquireAndEnsureOpen();\n        long start = time.nanoseconds();\n        try {\n            throwIfGroupIdNotDefined();\n            final Map<TopicPartition, OffsetAndMetadata> offsets;\n            offsets = coordinator.fetchCommittedOffsets(partitions, time.timer(timeout));\n            if (offsets == null) {\n                throw new TimeoutException(\"Timeout of \" + timeout.toMillis() + \"ms expired before the last \" +\n                        \"committed offset for partitions \" + partitions + \" could be determined. Try tuning \" +\n                        ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG + \" larger to relax the threshold.\");\n            } else {\n                offsets.forEach(this::updateLastSeenEpochIfNewer);\n                return offsets;\n            }\n        } finally {\n            kafkaConsumerMetrics.recordCommitted(time.nanoseconds() - start);\n            release();\n        }\n    }\n\n    @Override\n    public Uuid clientInstanceId(Duration timeout) {\n        if (clientTelemetryReporter.isEmpty()) {\n            throw new IllegalStateException(\"Telemetry is not enabled. Set config `\" + ConsumerConfig.ENABLE_METRICS_PUSH_CONFIG + \"` to `true`.\");\n\n        }","sourceCodeStart":892,"sourceCodeEnd":928,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java#L892-L928","documentation":"Thrown by KafkaConsumer.committed(Set, Duration) when the group coordinator returns null within the timeout, meaning committed offsets could not be fetched in time. The message explicitly suggests tuning default.api.timeout.ms larger. A null result from coordinator.fetchCommittedOffsets indicates the request timed out or the coordinator was unavailable, not that offsets are absent (absent offsets come back as a map with null values).","triggerScenarios":"Calling committed() with a group.id set but the coordinator unreachable; coordinator loading or in transition; network slow; default.api.timeout.ms too small for the cluster; calling committed() immediately after subscribe() before FindCoordinator completes.","commonSituations":"Cloud deployments with high latency to brokers; large consumer groups during coordinator failover; default.api.timeout.ms left at default (often 60s) but overridden lower; using committed() in health checks that run on a tight timer.","solutions":["Increase default.api.timeout.ms in consumer config as the message suggests.","Pass an explicit larger Duration: consumer.committed(tps, Duration.ofMinutes(2)).","Retry with backoff on TimeoutException; ensure group coordinator is reachable and stable.","Confirm group.id is set and the coordinator node is not under heavy load or in the middle of a rebalance."],"exampleFix":"// before\nMap<TopicPartition, OffsetAndMetadata> c = consumer.committed(tps);\n\n// after\nprops.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 120000);\nMap<TopicPartition, OffsetAndMetadata> c = consumer.committed(tps, Duration.ofMinutes(2));","handlingStrategy":"retry","validationCode":"// Validate inputs you control, then call with an explicit, oversized timeout:\nif (partitions == null || partitions.isEmpty()) return Map.of();\nDuration timeout = Duration.ofMillis(\n    Math.max(defaultApiTimeoutMs, 60_000));\nconsumer.committed(partitions, timeout);","typeGuard":null,"tryCatchPattern":"// Retry committed() with a larger timeout; the message itself points at DEFAULT_API_TIMEOUT_MS_CONFIG:\ntry {\n    return consumer.committed(partitions, Duration.ofSeconds(60));\n} catch (TimeoutException e) {\n    log.warn(\"committed() timed out, retrying with 120s\", e);\n    return consumer.committed(partitions, Duration.ofSeconds(120));\n}","preventionTips":["Set default.api.timeout.ms and request.timeout.ms deliberately in ConsumerConfig — defaults are tight for cold-start/coordinator-failover cases.","Ensure group.id is set and the consumer has had a successful first poll() so the coordinator is known before you call committed().","Cache committed offsets in your application if you query them repeatedly within a short window; they don't change until the next commit."],"tags":["consumer","timeout","coordinator","network","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}