apache/druid · error · UnsupportedOperationException

getPosition() is not supported in Kinesis

Error message

getPosition() is not supported in Kinesis

What it means

KinesisRecordSupplier does not implement getPosition; Kinesis partitions are tracked by sequence numbers, and the supplier exposes them via other APIs (getSequenceNumber, getPartitionTimeLag). Calling getPosition throws UnsupportedOperationException by design.

Source

Thrown at extensions-core/kinesis-indexing-service/src/main/java/org/apache/druid/indexing/kinesis/KinesisRecordSupplier.java:643

  @Override
  public void seekToEarliest(Set<StreamPartition<String>> partitions) throws InterruptedException
  {
    filterBufferAndResetBackgroundFetch(partitions);
    partitions.forEach(partition -> partitionSeek(partition, null, ShardIteratorType.TRIM_HORIZON));
  }

  @Override
  public void seekToLatest(Set<StreamPartition<String>> partitions) throws InterruptedException
  {
    filterBufferAndResetBackgroundFetch(partitions);
    partitions.forEach(partition -> partitionSeek(partition, null, ShardIteratorType.LATEST));
  }

  @Nullable
  @Override
  public String getPosition(StreamPartition<String> partition)
  {
    throw new UnsupportedOperationException("getPosition() is not supported in Kinesis");
  }

  @Nonnull
  @Override
  public List<OrderedPartitionableRecord<String, String, KinesisRecordEntity>> poll(long timeout)
  {
    start();

    try {
      List<MemoryBoundLinkedBlockingQueue.ObjectContainer<OrderedPartitionableRecord<String, String, KinesisRecordEntity>>> polledRecords = new ArrayList<>();

      records.drain(
          polledRecords,
          maxBytesPerPoll,
          timeout,
          TimeUnit.MILLISECONDS
      );

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Replace the getPosition call with getSequenceNumber(partition) which returns the current Kinesis sequence number
  2. Gate generic supplier code on supplier type before calling getPosition
  3. Use getPartitionTimeLag or partition offsets in the datasource metadata table instead

Example fix

// before
String pos = supplier.getPosition(partition);
// after
String seqNum = supplier.getSequenceNumber(partition);
Defensive patterns

Strategy: type-guard

Validate before calling

if (supplier instanceof KinesisRecordSupplier) {
  throw new UnsupportedOperationException("use getSequenceNumber instead of getPosition for Kinesis");
}

Type guard

static boolean supportsGetPosition(RecordSupplier<?, ?, ?> supplier) {
  return !(supplier instanceof KinesisRecordSupplier);
}

Try / catch

try {
  position = supplier.getPosition(partition);
} catch (UnsupportedOperationException e) {
  position = supplier.getSequenceNumber(partition); // Kinesis fallback
}

Prevention

When it happens

Trigger: Direct invocation of getPosition(StreamPartition) on a KinesisRecordSupplier — typically generic code written for Kafka suppliers that assumes getPosition exists for all record suppliers.

Common situations: Framework/plugin code written against Kafka's KafkaRecordSupplier reused with Kinesis; custom metadata-storage or monitoring code reading current partition position; copy-pasted supplier-agnostic utilities.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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