flowable/flowable-engine · error · IllegalStateException

Could not resolve the KafkaListenerContainerFactory to use f

Error message

Could not resolve the KafkaListenerContainerFactory to use for [<endpoint>] no factory was given and no default is set.

What it means

Modeled after Spring Kafka's KafkaListenerEndpointRegistrar: when no containerFactory was set directly and no containerFactoryBeanName is configured, the registrar cannot obtain a KafkaListenerContainerFactory for the endpoint and throws IllegalStateException. Every Kafka listener endpoint needs a container factory to create its MessageListenerContainer.

Source

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

        // This also makes sure that we are not going to start our listener earlier than the KafkaListenerEndpointRegistry
        boolean startImmediately = contextRefreshed || endpointRegistry.isRunning();
        logger.info("Registering endpoint {}", endpoint);
        endpointRegistry.registerListenerContainer(endpoint, resolveContainerFactory(endpoint, factory), startImmediately);
        logger.info("Finished registering endpoint {}", endpoint);
    }

    protected KafkaListenerContainerFactory<?> resolveContainerFactory(KafkaListenerEndpoint endpoint, KafkaListenerContainerFactory<?> containerFactory) {
        if (containerFactory != null) {
            return containerFactory;
        } else if (this.containerFactory != null) {
            return this.containerFactory;
        } else if (containerFactoryBeanName != null) {
            Assert.state(beanFactory != null, "BeanFactory must be set to obtain container factory by bean name");
            // Consider changing this if live change of the factory is required...
            this.containerFactory = beanFactory.getBean(containerFactoryBeanName, KafkaListenerContainerFactory.class);
            return this.containerFactory;
        } else {
            throw new IllegalStateException("Could not resolve the " +
                KafkaListenerContainerFactory.class.getSimpleName() + " to use for [" +
                endpoint + "] no factory was given and no default is set.");
        }
    }

    protected String getEndpointId(ChannelModel channelModel, String tenantId) {
        String channelDefinitionKey = channelModel.getKey();
        if (!StringUtils.hasText(tenantId)) {
            return CHANNEL_ID_PREFIX + channelDefinitionKey;
        }
        return CHANNEL_ID_PREFIX + tenantId + "#" + channelDefinitionKey;
    }

    protected String getEndpointGroupId(KafkaInboundChannelModel channelDefinition, String id) {
        String groupId = resolveExpressionAsString(channelDefinition.getGroupId(), "groupId");
        if (groupId == null) {
            groupId = id;
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Define a ConcurrentKafkaListenerContainerFactory bean and let the processor pick it as default (set via KafkaChannelDefinitionProcessor#setContainerFactory).
  2. Set the containerFactoryBeanName (e.g. "kafkaListenerContainerFactory") so it is looked up from the BeanFactory.
  3. Ensure beanFactory is set on the registrar when resolving by name.
  4. Add a spring-kafka annotation-driven configuration (@EnableKafka with default factory) to the application context.

Example fix

// before
// no factory bean defined
// after
@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(ConsumerFactory<String, String> cf) {
    ConcurrentKafkaListenerContainerFactory<String, String> f = new ConcurrentKafkaListenerContainerFactory<>();
    f.setConsumerFactory(cf);
    return f;
}
Defensive patterns

Strategy: validation

Validate before calling

if (applicationContext.getBeansOfType(KafkaListenerContainerFactory.class).isEmpty()
        && !applicationContext.containsBean("kafkaListenerContainerFactory")) {
    throw new IllegalStateException("No KafkaListenerContainerFactory bean defined");
}

Try / catch

try {
    deployChannel(channelModel);
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("no factory was given and no default is set")) {
        log.error("Define a KafkaListenerContainerFactory bean", e);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Registering an inbound Kafka channel endpoint when neither the default container factory on the processor nor a containerFactoryBeanName is available (beanFactory also unset for name lookup).

Common situations: Missing KafkaListenerContainerFactory bean in the Spring context; channel model omitted the container factory reference; running outside a fully wired Spring application context.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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