apache/kafka · error · IllegalStateException
No current assignment for partition ${tp}
Error message
No current assignment for partition ${tp} What it means
Thrown by SubscriptionState.assignedState(TopicPartition) when the partition is not present in the consumer's current assignment (assignment.stateValue(tp) returns null). It is a programmer-error guard: any operation that needs an assigned partition (seek, position, commit, pause/resume) routes through assignedState, so calling them on an unassigned partition is illegal. The client never recovers from this internally; the caller must respect the consumer protocol (subscribe + poll, then operate).
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/SubscriptionState.java:429
else if (groupSubscription.containsAll(subscription))
return groupSubscription;
else {
// When subscription changes `groupSubscription` may be outdated, ensure that
// new subscription topics are returned.
Set<String> topics = new HashSet<>(groupSubscription);
topics.addAll(subscription);
return topics;
}
}
synchronized boolean needsMetadata(String topic) {
return subscription.contains(topic) || groupSubscription.contains(topic);
}
private TopicPartitionState assignedState(TopicPartition tp) {
TopicPartitionState state = this.assignment.stateValue(tp);
if (state == null)
throw new IllegalStateException("No current assignment for partition " + tp);
return state;
}
private TopicPartitionState assignedStateOrNull(TopicPartition tp) {
return this.assignment.stateValue(tp);
}
public synchronized void seekValidated(TopicPartition tp, FetchPosition position) {
assignedState(tp).seekValidated(position);
}
public void seek(TopicPartition tp, long offset) {
seekValidated(tp, new FetchPosition(offset));
}
public void seekUnvalidated(TopicPartition tp, FetchPosition position) {
assignedState(tp).seekUnvalidated(position);
}View on GitHub (pinned to c31c9215e1)
Solutions
- Ensure consumer.poll() (or poll(Duration) in async API) has returned and consumer.assignment().contains(tp) is true before calling seek/position/pause.
- Inside a ConsumerRebalanceListener, only invoke partition-scoped operations in onPartitionsAssigned, never in onPartitionsRevoked.
- If using assign() manually, call consumer.partitionsFor(topic) first and only assign partitions that actually exist in the returned list.
- Refresh any cached TopicPartition set after every rebalance instead of holding a stale collection.
Example fix
// before
consumer.subscribe(Collections.singleton("orders"));
consumer.seek(new TopicPartition("orders", 0), 0); // throws: no assignment yet
// after
consumer.subscribe(Collections.singleton("orders"));
consumer.poll(Duration.ofMillis(500)); // triggers assignment
if (consumer.assignment().contains(new TopicPartition("orders", 0))) {
consumer.seek(new TopicPartition("orders", 0), 0);
} Defensive patterns
Strategy: validation
Validate before calling
// Operate on a partition only after confirming it is in the current assignment.
Set<TopicPartition> assigned = consumer.assignment();
if (!assigned.contains(tp)) {
// either wait for the next poll()/rebalance, or skip the per-partition op
return;
}
consumer.seek(tp, offset); // safe: assignedState(tp) will resolve Type guard
import org.apache.kafka.common.TopicPartition;
import java.util.Set;
/** True iff tp is part of the consumer's live assignment (safe to seek/position/commit). */
static boolean isAssigned(org.apache.kafka.clients.consumer.Consumer<?,?> c, TopicPartition tp) {
return tp != null && c.assignment().contains(tp);
} Try / catch
try {
consumer.seek(tp, offset);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("No current assignment")) {
// partition dropped in a rebalance: re-poll to refresh assignment, then retry or skip
consumer.poll(Duration.ofMillis(0));
} else {
throw e;
}
} Prevention
- Only invoke seek/position/commit/offsetsForTimes on partitions returned by consumer.assignment().
- Cache assignment right after poll() rather than holding stale TopicPartition refs across iterations.
- Use a ConsumerRebalanceListener to invalidate local per-partition state on revoke.
- Treat assignment as ephemeral: re-validate on every loop iteration after poll().
When it happens
Trigger: Calling consumer.seek(tp, offset), consumer.position(tp), consumer.committed(tp), consumer.pause(tp)/resume(tp), or requesting a reset for a TopicPartition that was never assigned to this consumer instance. Also seen when a rebalance revoked the partition between the last poll() and the subsequent call, or when using manual assignment (assign()) with a partition that is not in the cluster metadata yet.
Common situations: Mixing subscribe() with seek() before the first poll() returns assignments; caching TopicPartition references across rebalances without refreshing from consumer.assignment(); calling position() inside a ConsumerRebalanceListener before partitions are formally assigned; in the new async consumer, calling seek on a partition that the background thread has not yet wired up.
Related errors
- Topic partitions collection to assign to cannot be null
- Attempt to retrieve value from future which hasn't successfu
- You can only check the position for partitions assigned to t
- To use the group management or offset commit APIs, you must
- The target time for partition {} is {}. The target time cann
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/19c391fd65b2ad39.json.
Report an issue: GitHub.