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

  1. No action needed — returning true means the lookup is running; rely on this idempotency
  2. If you need a fresh consumer, call stop() then start(), noting that after shutdown() the factory can never restart (create a new factory instead)
  3. Serialize start/stop calls if multiple threads race to start the same lookup
  4. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1e091a67d66be41a. Report an issue: GitHub.