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
- Replace the getPosition call with getSequenceNumber(partition) which returns the current Kinesis sequence number
- Gate generic supplier code on supplier type before calling getPosition
- 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
- Never call getPosition on Kinesis suppliers; use getSequenceNumber or getPartitionTimeLag
- Guard generic supplier-agnostic code by supplier type before position-based APIs
- Read the KinesisRecordSupplier Javadoc — position semantics differ from Kafka
- Add unit tests covering all supplier implementations you plug into generic utilities
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
- This supervisor type does not support partition expiration.
- Casting to float type is not supported
- Casting to long type is not supported
- Not implemented
- Not implemented
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/0c4687da6edbc7c2.
Report an issue: GitHub.