apache/druid · error · IllegalArgumentException

SeekableStreamSupervisorIOConfig does not support both prope

Error message

SeekableStreamSupervisorIOConfig does not support both properties lateMessageRejectionStartDateTime and lateMessageRejectionPeriod.

What it means

SeekableStreamSupervisorIOConfig allows limiting late messages either by a relative period (lateMessageRejectionPeriod) or by an absolute datetime (lateMessageRejectionStartDateTime), but not both. The constructor validates this mutual exclusivity and throws IAE when both are set in the supervisor spec.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorIOConfig.java:139

    this.stopTaskCount = stopTaskCount;
    this.taskDuration = defaultDuration(taskDuration, "PT1H");
    this.startDelay = defaultDuration(startDelay, "PT5S");
    this.period = defaultDuration(period, "PT30S");
    this.useEarliestSequenceNumber = useEarliestSequenceNumber != null ? useEarliestSequenceNumber : false;
    this.completionTimeout = defaultDuration(completionTimeout, "PT30M");
    this.lateMessageRejectionPeriod = lateMessageRejectionPeriod == null
                                      ? Optional.absent()
                                      : Optional.of(lateMessageRejectionPeriod.toStandardDuration());
    this.lateMessageRejectionStartDateTime = lateMessageRejectionStartDateTime == null
                                      ? Optional.absent()
                                      : Optional.of(lateMessageRejectionStartDateTime);
    this.earlyMessageRejectionPeriod = earlyMessageRejectionPeriod == null
                                       ? Optional.absent()
                                       : Optional.of(earlyMessageRejectionPeriod.toStandardDuration());

    if (this.lateMessageRejectionPeriod.isPresent()
                && this.lateMessageRejectionStartDateTime.isPresent()) {
      throw new IAE("SeekableStreamSupervisorIOConfig does not support "
                + "both properties lateMessageRejectionStartDateTime "
          + "and lateMessageRejectionPeriod.");
    }

    this.idleConfig = idleConfig;
    this.serverPriorityToReplicas = serverPriorityToReplicas;
    this.boundedStreamConfig = boundedStreamConfig;

    if (this.serverPriorityToReplicas != null) {
      int serverPriorityReplicas = 0;
      for (Map.Entry<Integer, Integer> entry : this.serverPriorityToReplicas.entrySet()) {
        final Integer serverReplica = entry.getValue();

        if (serverReplica == null || serverReplica < 0) {
          throw InvalidInput.exception(
              "Found invalid server replica[%d] for priority[%d] in serverPriorityToReplicas[%s]. Replicas must be >= 0.",
              serverReplica, entry.getKey(), serverPriorityToReplicas
          );

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove lateMessageRejectionStartDateTime and keep only lateMessageRejectionPeriod (relative window), or vice versa.
  2. Use lateMessageRejectionStartDateTime for a one-time cutoff (e.g. after a backfill) and lateMessageRejectionPeriod for an ongoing rolling window.
  3. If generating specs from templates, ensure only one of the two keys is ever emitted.

Example fix

// before
"ioConfig": {
  "lateMessageRejectionPeriod": "P7D",
  "lateMessageRejectionStartDateTime": "2024-01-01T00:00:00Z"
}
// after: keep only one
"ioConfig": {
  "lateMessageRejectionPeriod": "P7D"
}
Defensive patterns

Strategy: validation

Validate before calling

if (ioConfig.lateMessageRejectionPeriod != null && ioConfig.lateMessageRejectionStartDateTime != null) {
    throw new IllegalArgumentException("Set only one of lateMessageRejectionPeriod / lateMessageRejectionStartDateTime");
}

Try / catch

try { submitSupervisorSpec(spec); } catch (IAE e) { if (e.getMessage().contains("lateMessageRejection")) { stripConflictingProperty(spec); } }

Prevention

When it happens

Trigger: Submitting/creating a supervisor spec whose ioConfig contains both lateMessageRejectionPeriod and lateMessageRejectionStartDateTime non-null.

Common situations: Copy-pasting spec fragments that each carried one of the two properties; merging old and new ingestion specs during migration; templated spec generation accidentally filling both fields.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/800b82bfbad8871b. Report an issue: GitHub.