apache/druid · error · IllegalStateException
Partition [%s] has not been assigned
Error message
Partition [%s] has not been assigned
What it means
partitionSeek looks up the PartitionResource for the given StreamPartition and throws this ISE if none has been assigned. A seek (and the public seek/seekToEarliest/seekToLatest paths that route through it) is only legal after the partition was assigned to this supplier.
Source
Thrown at extensions-core/kinesis-indexing-service/src/main/java/org/apache/druid/indexing/kinesis/KinesisRecordSupplier.java:915
public boolean isAnyFetchActive()
{
return partitionResources.values()
.stream()
.map(pr -> pr.currentFetch)
.anyMatch(fetch -> (fetch != null && !fetch.isDone()));
}
/**
* Check that a {@link PartitionResource} has been assigned to this record supplier, and if so call
* {@link PartitionResource#seek} to move it to the latest offsets. Note that this method does not restart background
* fetch, which should have been stopped prior to calling this method by a call to
* {@link #filterBufferAndResetBackgroundFetch}.
*/
private void partitionSeek(StreamPartition<String> partition, String sequenceNumber, ShardIteratorType iteratorEnum)
{
PartitionResource resource = partitionResources.get(partition);
if (resource == null) {
throw new ISE("Partition [%s] has not been assigned", partition);
}
resource.seek(iteratorEnum, sequenceNumber);
}
/**
* Given a partition and a {@link ShardIteratorType}, create a shard iterator and fetch
* {@link #GET_SEQUENCE_NUMBER_RECORD_COUNT} records and return the first sequence number from the result set.
* This method is thread safe as it does not depend on the internal state of the supplier (it doesn't use the
* {@link PartitionResource} which have been assigned to the supplier), and the Kinesis client is thread safe.
* <p>
* When there are no records at the offset corresponding to the ShardIteratorType,
* If shard is closed, return custom EOS sequence marker
* While getting the earliest sequence number, return a custom marker corresponding to TRIM_HORIZON
* While getting the most recent sequence number, return a custom marker corresponding to LATEST
*/
@Nullable
private String getSequenceNumber(StreamPartition<String> partition, ShardIteratorType iteratorEnum)
{View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure assign(...) (or setStream/partition assignment) is called with the partition before seeking it
- List current shards via getPartitionIds and seek only shards present in the assignment
- Refresh shard map after resharding — closed shards cannot be seeked by iterator; use their ending sequence number
- Verify the partition key (stream name + shard id) matches exactly what was assigned
Example fix
// before
supplier.seek(partition, sequenceNumber);
// after
if (assignedPartitions.contains(partition)) {
supplier.seek(partition, sequenceNumber);
} else {
LOG.warn("Skipping seek for unassigned partition %s", partition);
} Defensive patterns
Strategy: validation
Validate before calling
Set<StreamPartition<String>> assigned = supplier.getAssignment();
if (assigned == null || !assigned.contains(partition)) {
throw new IllegalArgumentException("seek requires partition assigned: " + partition);
} Type guard
static boolean canSeek(KinesisRecordSupplier s, StreamPartition<String> p) {
return s.getAssignment() != null && s.getAssignment().contains(p);
} Try / catch
try {
supplier.seek(partition, seqNum);
} catch (ISE e) {
if (e.getMessage().contains("has not been assigned")) {
supplier.assign(partitions); // re-assign then retry
supplier.seek(partition, seqNum);
} else throw e;
} Prevention
- Always call assign() (directly or via seek setup) before any seek
- Re-derive shard lists after stream resharding; skip shards that were merged/closed
- Compare StreamPartition equality (stream + shardId) exactly as assigned
- Check metadata storage assignment matches the partitions you seek
When it happens
Trigger: Calling seek/seekToEarliest/seekToLatest (or partitionSeek directly) with a StreamPartition that was never added via assign/partition assignment, or after assignment was cleared.
Common situations: Seeking a shard that was split/merged away and is no longer in the assignment list; task restart where assignment did not include the partition in metadata; typos or stale partitions after stream resharding.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- StreamException
- can't reschedule fetch records runnable, recordsResult is nu
- RuntimeException
- getPosition() is not supported in Kinesis
- Invalid operation - KinesisRecordSupplier has already been c
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/bd9c5fe226818524.
Report an issue: GitHub.