apache/druid · info
Already started, not starting again
Error message
Already started, not starting again
What it means
KafkaLookupExtractorFactory.start() is idempotent: if the lookup has already been started, it logs this warning and returns true without starting a second Kafka consumer. The same lock also refuses to restart after shutdown. Callers get true (already/now running) or false (cannot start).
Source
Thrown at extensions-core/kafka-extraction-namespace/src/main/java/org/apache/druid/query/lookup/KafkaLookupExtractorFactory.java:157
return kafkaProperties;
}
public long getConnectTimeout()
{
return connectTimeout;
}
public boolean isInjective()
{
return injective;
}
@Override
public boolean start()
{
synchronized (started) {
if (started.get()) {
LOG.warn("Already started, not starting again");
return true;
}
if (executorService.isShutdown()) {
LOG.warn("Already shut down, not starting again");
return false;
}
verifyKafkaProperties();
final String topic = getKafkaTopic();
LOG.debug("About to listen to topic [%s] with group.id [%s]", topic, factoryId);
// this creates a ConcurrentMap
cacheHandler = cacheManager.createCache();
final Map<String, String> map = cacheHandler.getCache();
mapRef.set(map);
final CountDownLatch startingReads = new CountDownLatch(1);
View on GitHub (pinned to 9b90983fd2)
Solutions
- No action needed — returning true means the lookup is running; rely on this idempotency
- If you need a fresh consumer, call stop() then start(), noting that after shutdown() the factory can never restart (create a new factory instead)
- Serialize start/stop calls if multiple threads race to start the same lookup
- In tests, create a new factory instance per test case
Example fix
// before
factory.start();
factory.start(); // logs "Already started, not starting again"
// after
if (!factory.start()) {
throw new IllegalStateException("lookup failed to start");
} // or create a new KafkaLookupExtractorFactory for a fresh consumer Defensive patterns
Strategy: type-guard
Validate before calling
if (factory.isStarted()) { /* skip start() */ } Type guard
static boolean safeStart(KafkaLookupExtractorFactory f) { return f.isStarted() || f.start(); } Prevention
- Check isStarted() before calling start() in custom code
- Create a new factory instance after stop()/shutdown; factories cannot restart after shutdown
- Serialize lookup lifecycle calls across threads
When it happens
Trigger: Calling start() twice on the same KafkaLookupExtractorFactory instance, e.g. lookup manager re-initialization races, or a test calling start() without stop() in between.
Common situations: Druid lookup configuration hot-reloads where the same factory object is started again, concurrent start attempts from multiple threads, or unit tests (testStartFailsOn*) that start once before exercising failure paths.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Already shut down, not starting again
- Factory [%s] not started
- %s: %s, extractorID = %s
- New sequence startOffset[%s] does not equal expected prior o
- Exclusive start partitions[%s] for new sequence don't match
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1e091a67d66be41a.
Report an issue: GitHub.