{"record":{"id":"aec92a5b17f204b8","repo":"apache/druid","slug":"previous-sequencenumber-s-is-no-longer-availabl","errorCode":null,"errorMessage":"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.","messagePattern":"Previous sequenceNumber \\[(.+?)\\] is no longer available for partition \\[(.+?)\\]\\. You can clear the previous sequenceNumber and start reading from a valid message by using the supervisor's reset API\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java","lineNumber":4619,"sourceCode":"                                  \"Bounded supervisor detected existing metadata from a different run. \"\n                                  + \"Metadata bounded config [%s] does not match current config [%s]. \"\n                                  + \"To start a new bounded ingestion, either: \"\n                                  + \"(1) use the supervisor reset API to clear existing metadata, or \"\n                                  + \"(2) use a different supervisor ID.\",\n                                  metadataBoundedConfig,\n                                  currentBoundedConfig\n                              );\n        }\n      }\n\n      log.debug(\"Getting sequence [%s] from metadata storage for partition [%s]\", sequence, partition);\n      if (!taskTuningConfig.isSkipSequenceNumberAvailabilityCheck()) {\n        if (!checkOffsetAvailability(partition, sequence)) {\n          if (taskTuningConfig.isResetOffsetAutomatically()) {\n            partitionsToReset.put(partition, sequence);\n            return null;\n          } else {\n            throw new StreamException(\n                new ISE(\n                    \"Previous sequenceNumber [%s] is no longer available for partition [%s]. You can clear the previous\"\n                    + \" sequenceNumber and start reading from a valid message by using the supervisor's reset API.\",\n                    sequence,\n                    partition\n                )\n            );\n          }\n        }\n      }\n      return makeSequenceNumber(sequence, useExclusiveStartSequenceNumberForNonFirstSequence());\n    } else {\n      // NEW: In bounded mode, if no checkpoint exists (task failed before first checkpoint),\n      // fall back to bounded start offset\n      if (ioConfig.isBounded()) {\n        BoundedStreamConfig boundedConfig = ioConfig.getBoundedStreamConfig();\n        Map<PartitionIdType, SequenceOffsetType> startOffsets =\n            convertBoundedConfigMap(boundedConfig.getStartSequenceNumbers());","sourceCodeStart":4601,"sourceCodeEnd":4637,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java#L4601-L4637","documentation":"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.","triggerScenarios":"Task/iteration start calls checkOffsetAvailability(partition, sequence), it returns false, taskTuningConfig.isResetOffsetAutomatically() is false and isSkipSequenceNumberAvailabilityCheck() is false.","commonSituations":"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.","solutions":["Run the supervisor reset API (POST /druid/indexer/v1/supervisor/<id>/reset) to clear the stale sequence numbers, then resume.","Set resetOffsetAutomatically: true in tuning config if silently skipping to available offsets is acceptable.","Set resetOffsetAutomatically: false + skipSequenceNumberAvailabilityCheck: true only if you know the check is a false positive (e.g. consumer lag).","Increase stream retention so short outages don't invalidate offsets."],"exampleFix":"// before\n\"tuningConfig\": { \"type\": \"kinesis\", \"resetOffsetAutomatically\": false }\n// after: automatic reset instead of hard failure\n\"tuningConfig\": { \"type\": \"kinesis\", \"resetOffsetAutomatically\": true }","handlingStrategy":"try-catch","validationCode":"// verify saved offsets still exist before resuming supervisor\nfor (var e : savedOffsets.entrySet()) assert checkOffsetAvailability(e.getKey(), e.getValue());","typeGuard":null,"tryCatchPattern":"try { startSupervisor(); } catch (StreamException e) { if (e.getMessage().contains(\"no longer available\")) { callResetApi(); startSupervisor(); } }","preventionTips":["Increase Kafka retention.ms / Kinesis retention period","Use supervisor reset API instead of editing metadata manually","Enable resetOffsetAutomatically for unattended recovery","Avoid deleting/recreating streams under active supervisors"],"tags":["druid","supervisor","offsets","reset"],"backgroundTag":"offset-out-of-range","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}