flowable/flowable-engine · error · IllegalStateException

At least one of topics, topicPartitions or topicPattern must

Error message

At least one of topics, topicPartitions or topicPattern must be provided for <endpoint>

What it means

SimpleKafkaListenerEndpoint must have at least one subscription target before the listener container starts. If topicPattern is null and both the topics list and topicPartitions map are empty, afterPropertiesSet throws IllegalStateException because the endpoint would subscribe to nothing.

Source

Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/SimpleKafkaListenerEndpoint.java:180

    }

    public void setMainListenerId(String mainListenerId) {
        this.mainListenerId = mainListenerId;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        boolean topicsEmpty = getTopics().isEmpty();
        boolean topicPartitionsEmpty = ObjectUtils.isEmpty(getTopicPartitionsToAssign());
        if (!topicsEmpty && !topicPartitionsEmpty) {
            throw new IllegalStateException("Topics or topicPartitions must be provided but not both for " + this);
        }
        if (this.topicPattern != null && (!topicsEmpty || !topicPartitionsEmpty)) {
            throw new IllegalStateException("Only one of topics, topicPartitions or topicPattern must are allowed for "
                    + this);
        }
        if (this.topicPattern == null && topicsEmpty && topicPartitionsEmpty) {
            throw new IllegalStateException("At least one of topics, topicPartitions or topicPattern must be provided "
                    + "for " + this);
        }
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "[" + this.id
            + "] topics=" + this.topics
            + "' | topicPattern='" + this.topicPattern + "'"
            + "' | topicPartitions='" + this.topicPartitions + "'"
            + " | messageListener='" + messageListener + "'";
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Call setTopics(...) with at least one topic name
  2. Or call setTopicPattern(...) with a regex if dynamic matching is intended
  3. Or call setTopicPartitionsToAssign(...) for manual partition assignment
  4. Check upstream configuration source (channel model properties, env vars) for blank values

Example fix

// before
SimpleKafkaListenerEndpoint endpoint = new SimpleKafkaListenerEndpoint();
endpoint.setMessageListener(listener);
// after
SimpleKafkaListenerEndpoint endpoint = new SimpleKafkaListenerEndpoint();
endpoint.setTopics(Collections.singletonList("my-topic"));
endpoint.setMessageListener(listener);
Defensive patterns

Strategy: validation

Validate before calling

if (endpoint.getTopicPattern() == null && endpoint.getTopics().isEmpty() && ObjectUtils.isEmpty(endpoint.getTopicPartitionsToAssign())) {
    throw new IllegalArgumentException("SimpleKafkaListenerEndpoint requires topics, topicPartitions, or a topicPattern");
}

Type guard

boolean hasNoSubscription(SimpleKafkaListenerEndpoint e) {
    return e.getTopicPattern() == null && e.getTopics().isEmpty() && ObjectUtils.isEmpty(e.getTopicPartitionsToAssign());
}

Try / catch

try {
    endpoint.afterPropertiesSet();
} catch (IllegalStateException ex) {
    log.error("Endpoint has no subscription target: {}", ex.getMessage());
    throw ex;
}

Prevention

When it happens

Trigger: Creating a SimpleKafkaListenerEndpoint, setting the message listener, but forgetting to set any of topics, topicPartitionsToAssign, or topicPattern before container registration.

Common situations: Dynamically built endpoints where topic values come from empty/missing configuration (e.g. empty environment variable, blank channel-model field); beans created but not yet configured at startup time.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/9ef29e2231602023. Report an issue: GitHub.