apache/druid · error · IllegalStateException

Previous sequenceNumber

Error message

Previous sequenceNumber [%s] is no longer available for partition [%s]. You can clear the previous sequenceNumber and start reading from a valid message by using the supervisor's reset API.

What it means

The supervisor checks that each partition's stored sequence number still exists in the stream. When it does not, and automatic reset is disabled and skipSequenceNumberAvailabilityCheck is false, it throws a StreamException (ISE) telling the operator to clear the stored offset via the supervisor reset API before ingestion can proceed.

Solutions

  1. Run the supervisor reset API (POST /druid/indexer/v1/supervisor/<id>/reset) to clear the stale sequence numbers, then resume.
  2. Set resetOffsetAutomatically: true in tuning config if silently skipping to available offsets is acceptable.
  3. Set resetOffsetAutomatically: false + skipSequenceNumberAvailabilityCheck: true only if you know the check is a false positive (e.g. consumer lag).
  4. Increase stream retention so short outages don't invalidate offsets.

Example fix

// before
"tuningConfig": { "type": "kinesis", "resetOffsetAutomatically": false }
// after: automatic reset instead of hard failure
"tuningConfig": { "type": "kinesis", "resetOffsetAutomatically": true }
Defensive patterns

Strategy: try-catch

Validate before calling

// verify saved offsets still exist before resuming supervisor
for (var e : savedOffsets.entrySet()) assert checkOffsetAvailability(e.getKey(), e.getValue());

Try / catch

try { startSupervisor(); } catch (StreamException e) { if (e.getMessage().contains("no longer available")) { callResetApi(); startSupervisor(); } }

Prevention

When it happens

Trigger: Task/iteration start calls checkOffsetAvailability(partition, sequence), it returns false, taskTuningConfig.isResetOffsetAutomatically() is false and isSkipSequenceNumberAvailabilityCheck() is false.

Common situations: Kafka topic retention deleted offsets during downtime; Kinesis shards expired or merged; the stream was deleted and recreated with fresh offsets; replication lag making the offset unreadable on the replica read from.

Related errors


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

Appendix: source

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

                                  "Bounded supervisor detected existing metadata from a different run. "
                                  + "Metadata bounded config [%s] does not match current config [%s]. "
                                  + "To start a new bounded ingestion, either: "
                                  + "(1) use the supervisor reset API to clear existing metadata, or "
                                  + "(2) use a different supervisor ID.",
                                  metadataBoundedConfig,
                                  currentBoundedConfig
                              );
        }
      }

      log.debug("Getting sequence [%s] from metadata storage for partition [%s]", sequence, partition);
      if (!taskTuningConfig.isSkipSequenceNumberAvailabilityCheck()) {
        if (!checkOffsetAvailability(partition, sequence)) {
          if (taskTuningConfig.isResetOffsetAutomatically()) {
            partitionsToReset.put(partition, sequence);
            return null;
          } else {
            throw new StreamException(
                new ISE(
                    "Previous sequenceNumber [%s] is no longer available for partition [%s]. You can clear the previous"
                    + " sequenceNumber and start reading from a valid message by using the supervisor's reset API.",
                    sequence,
                    partition
                )
            );
          }
        }
      }
      return makeSequenceNumber(sequence, useExclusiveStartSequenceNumberForNonFirstSequence());
    } else {
      // NEW: In bounded mode, if no checkpoint exists (task failed before first checkpoint),
      // fall back to bounded start offset
      if (ioConfig.isBounded()) {
        BoundedStreamConfig boundedConfig = ioConfig.getBoundedStreamConfig();
        Map<PartitionIdType, SequenceOffsetType> startOffsets =
            convertBoundedConfigMap(boundedConfig.getStartSequenceNumbers());

View on GitHub (pinned to 9b90983fd2)