apache/seatunnel · error · IllegalArgumentException

start_mode.end_timestamp must not be greater than the curren

Error message

start_mode.end_timestamp must not be greater than the current time

What it means

When start_mode.end_timestamp is set (bounded consumption until a timestamp), KafkaSourceConfig validates that it is not greater than the current time. An end timestamp in the future is rejected with IllegalArgumentException because the bound cannot be resolved against existing offsets yet.

Source

Thrown at seatunnel-connectors-v2/connector-kafka/src/main/java/org/apache/seatunnel/connectors/seatunnel/kafka/source/KafkaSourceConfig.java:227

                                    long startOffsetsTimestamp =
                                            readonlyConfig.get(START_MODE_TIMESTAMP);
                                    long currentTimestamp = System.currentTimeMillis();
                                    // Runtime check: cannot be declarative (depends on current
                                    // time)
                                    if (startOffsetsTimestamp > currentTimestamp) {
                                        throw new IllegalArgumentException(
                                                "start_mode.timestamp must not be greater than the current time");
                                    }
                                    consumerMetadata.setStartOffsetsTimestamp(
                                            startOffsetsTimestamp);
                                    if (Objects.nonNull(
                                            readonlyConfig.get(START_MODE_END_TIMESTAMP))) {
                                        long endOffsetsTimestamp =
                                                readonlyConfig.get(START_MODE_END_TIMESTAMP);
                                        // Runtime check: cannot be declarative (depends on current
                                        // time)
                                        if (endOffsetsTimestamp > currentTimestamp) {
                                            throw new IllegalArgumentException(
                                                    "start_mode.end_timestamp must not be greater than the current time");
                                        }
                                        consumerMetadata.setEndOffsetsTimestamp(
                                                endOffsetsTimestamp);
                                    }
                                    break;
                                case SPECIFIC_OFFSETS:
                                    Map<String, Long> offsetMap =
                                            readonlyConfig.get(START_MODE_OFFSETS);
                                    Map<TopicPartition, Long> specificStartOffsets =
                                            new HashMap<>();
                                    offsetMap.forEach(
                                            (topicPartitionKey, offset) -> {
                                                int splitIndex = topicPartitionKey.lastIndexOf("-");
                                                String topic =
                                                        topicPartitionKey.substring(0, splitIndex);
                                                String partition =
                                                        topicPartitionKey.substring(splitIndex + 1);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set start_mode.end_timestamp to a past epoch-millis value (must be <= now).
  2. Compute end_timestamp at job submission time rather than hardcoding.
  3. If you want 'read until now and stop', use the latest/current-time semantics appropriate to the connector instead of a future timestamp.

Example fix

// before
start_mode.end_timestamp = 1893456000000  # future
// after
start_mode.end_timestamp = 1704067200000  # past epoch millis
Defensive patterns

Strategy: validation

Validate before calling

Long endTs = config.getStartModeEndTimestamp();
if (endTs != null && endTs > System.currentTimeMillis()) throw new IllegalArgumentException("start_mode.end_timestamp must be in the past (epoch millis)");

Try / catch

try { submitJob(cfg); } catch (IllegalArgumentException e) { if (e.getMessage().contains("end_timestamp")) fixEndTimestamp(cfg); else throw e; }

Prevention

When it happens

Trigger: Configuring start_mode=TIMESTAMP with start_mode.end_timestamp set to a future epoch-millis value; createConsumerMetadata performs the wall-clock comparison when building consumer metadata.

Common situations: Intending 'read up to now' but setting a future value; timezone/unit confusion (seconds vs millis); scheduling a job for later replay with a precomputed end time.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/d6337d3dcf321070. Report an issue: GitHub.