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

  1. Ensure consumer.poll() (or poll(Duration) in async API) has returned and consumer.assignment().contains(tp) is true before calling seek/position/pause.
  2. Inside a ConsumerRebalanceListener, only invoke partition-scoped operations in onPartitionsAssigned, never in onPartitionsRevoked.
  3. If using assign() manually, call consumer.partitionsFor(topic) first and only assign partitions that actually exist in the returned list.
  4. 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

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


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/19c391fd65b2ad39.json. Report an issue: GitHub.