apache/kafka · error · java.lang.IllegalStateException
Consumer is not subscribed to any topics or assigned any par
Error message
Consumer is not subscribed to any topics or assigned any partitions
What it means
Thrown by poll(Timer) when subscriptions.hasNoSubscriptionOrUserAssignment() is true. The consumer must have an active subscription (via subscribe) or a manual assignment (via assign) before it can fetch; otherwise there is nothing to poll and the call would return empty forever. Rejecting early surfaces the misuse as a clear IllegalStateException rather than a silent no-op.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java:651
release();
}
}
@Override
public ConsumerRecords<K, V> poll(final Duration timeout) {
return poll(time.timer(timeout));
}
/**
* @throws KafkaException if the rebalance callback throws exception
*/
private ConsumerRecords<K, V> poll(final Timer timer) {
acquireAndEnsureOpen();
try {
this.kafkaConsumerMetrics.recordPollStart(timer.currentTimeMs());
if (this.subscriptions.hasNoSubscriptionOrUserAssignment()) {
throw new IllegalStateException("Consumer is not subscribed to any topics or assigned any partitions");
}
do {
client.maybeTriggerWakeup();
// try to update assignment metadata BUT do not need to block on the timer for join group
updateAssignmentMetadataIfNeeded(timer, false);
final Fetch<K, V> fetch = pollForFetches(timer);
if (!fetch.isEmpty()) {
// before returning the fetched records, we can send off the next round of fetches
// and avoid block waiting for their responses to enable pipelining while the user
// is handling the fetched records.
//
// NOTE: since the consumed position has already been updated, we must not allow
// wakeups or any other errors to be triggered prior to returning the fetched records.
if (sendFetches() > 0 || client.hasPendingRequests()) {
client.transmitSends();View on GitHub (pinned to c31c9215e1)
Solutions
- Call consumer.subscribe(Collections.singletonList("my-topic")) or consumer.assign(partitions) before the first poll.
- After unsubscribe(), re-subscribe or re-assign before the next poll call.
- Guard poll in application code with a check that subscription/assignment has been established, especially in restart/reconnect paths.
Example fix
// before
try (KafkaConsumer<String,String> c = new KafkaConsumer<>(props)) {
ConsumerRecords<String,String> recs = c.poll(Duration.ofMillis(1000));
}
// after
try (KafkaConsumer<String,String> c = new KafkaConsumer<>(props)) {
c.subscribe(Collections.singletonList("events"));
ConsumerRecords<String,String> recs = c.poll(Duration.ofMillis(1000));
} Defensive patterns
Strategy: validation
Validate before calling
// Guarantee subscription/assignment is set before the first poll
if (!subscribed && !assigned) {
consumer.subscribe(java.util.List.of("my-topic"));
// OR: consumer.assign(List.of(new TopicPartition("my-topic", 0)));
}
org.apache.kafka.clients.consumer.ConsumerRecords<K,V> records = consumer.poll(java.time.Duration.ofMillis(500)); Type guard
// Application-level state flag
private boolean hasSubscriptionOrAssignment() {
return subscriptionSet || assignmentSet;
}
// Guard poll
if (!hasSubscriptionOrAssignment()) { throw new IllegalStateException(
"poll() called before subscribe()/assign()"); } Try / catch
try {
consumer.poll(timeout);
} catch (IllegalStateException e) {
// Initial poll before subscribe; recover by subscribing then retry
consumer.subscribe(java.util.List.of("my-topic"));
records = consumer.poll(timeout);
} Prevention
- Call subscribe() or assign() exactly once during consumer setup, before entering the poll loop
- Treat 'not subscribed or assigned' as a startup-ordering bug; fix the call order rather than catching it at runtime
- Track subscription state in your own flag if you dynamically (un)subscribe
When it happens
Trigger: Calling consumer.poll(...) before any consumer.subscribe(...) or consumer.assign(...) call. Calling poll after consumer.unsubscribe() without re-subscribing. Constructing a consumer and immediately polling.
Common situations: Startup ordering bug where poll runs before the subscription step. Conditional subscription logic that skips both branches. Cleanup/restart code that unsubscribes but does not re-establish subscription before the next poll loop.
Related errors
- Consumer is not subscribed to any topics or assigned any par
- This consumer has already been closed.
- Malformed consumer protocol subscription
- Unsupported subscription version: {}
- This RebalanceConsumer is already closed. Re-use of this obj
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/00cf0290c5b500b0.json.
Report an issue: GitHub.