prestodb/presto · error · IllegalArgumentException

Invalid Kafka Offset start/end pair: %s - %s

Error message

Invalid Kafka Offset start/end pair: %s - %s

What it means

getSplits validates the timestamp bounds from the KafkaTableLayoutHandle: if startTimestamp > endTimestamp it throws an IllegalArgumentException 'Invalid Kafka Offset start/end pair'. These timestamps translate to offsets via offsetsForTimes, so an inverted range is a caller/config error, not a Kafka failure.

Source

Thrown at presto-kafka/src/main/java/com/facebook/presto/kafka/KafkaSplitManager.java:109

            KafkaTableLayoutHandle layoutHandle = (KafkaTableLayoutHandle) layout;
            HostAddress node = KafkaClusterMetadataHelper.selectRandom(clusterMetadataSupplier.getNodes(layoutHandle.getTable().getSchemaName()));

            KafkaConsumer<ByteBuffer, ByteBuffer> consumer = consumerManager.createConsumer(Thread.currentThread().getName(), node);
            List<PartitionInfo> partitions = consumer.partitionsFor(topic);
            ImmutableList.Builder<ConnectorSplit> splits = ImmutableList.builder();

            for (PartitionInfo partition : partitions) {
                Node leader = partition.leader();
                if (leader == null) {
                    throw new PrestoException(GENERIC_INTERNAL_ERROR, format("Leader election in progress for Kafka topic '%s' partition %s", topic, partition.partition()));
                }

                HostAddress partitionLeader = HostAddress.fromParts(leader.host(), leader.port());
                long startTimestamp = layoutHandle.getStartOffsetTimestamp();
                long endTimestamp = layoutHandle.getEndOffsetTimestamp();

                if (startTimestamp > endTimestamp) {
                    throw new IllegalArgumentException(String.format("Invalid Kafka Offset start/end pair: %s - %s", startTimestamp, endTimestamp));
                }

                TopicPartition topicPartition = new TopicPartition(partition.topic(), partition.partition());
                consumer.assign(ImmutableList.of(topicPartition));

                long beginningOffset = (startTimestamp == 0) ?
                        consumer.beginningOffsets(ImmutableList.of(topicPartition)).values().iterator().next() :
                        findOffsetsByTimestamp(consumer, topicPartition, startTimestamp);
                long endOffset = (endTimestamp == 0) ?
                        consumer.endOffsets(ImmutableList.of(topicPartition)).values().iterator().next() :
                        findOffsetsByTimestamp(consumer, topicPartition, endTimestamp);

                KafkaSplit split = new KafkaSplit(
                        connectorId,
                        topic,
                        kafkaTableHandle.getKeyDataFormat(),
                        kafkaTableHandle.getMessageDataFormat(),
                        kafkaTableHandle.getKeyDataSchemaLocation().map(KafkaSplitManager::readSchema),

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the table's start-offset-timestamp/end-offset-timestamp properties so start <= end
  2. Correct the ordering of the values supplied by the calling tool/job
  3. Drop and recreate the table description with valid timestamp bounds

Example fix

// before
"startOffsetTimestamp": 1700000000000,
"endOffsetTimestamp": 1600000000000
// after
"startOffsetTimestamp": 1600000000000,
"endOffsetTimestamp": 1700000000000
Defensive patterns

Strategy: validation

Validate before calling

if (startOffsetTimestamp > endOffsetTimestamp)
    throw new IllegalArgumentException("start must be <= end");

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: A Kafka table layout was created with start-offset-timestamp greater than end-offset-timestamp (e.g. via a table property or session-level time-range constraint) and then getSplits runs a query on that table.

Common situations: Swapped start/end values in CREATE TABLE properties; a UI or scheduler passing (end, start) in the wrong order; timezone/unit confusion producing end < start.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/1e546ee4fd7b895d. Report an issue: GitHub.