apache/druid · error · IllegalStateException

start method returned false for lookup [%s]:[%s]

Error message

start method returned false for lookup [%s]:[%s]

What it means

Inside handle()'s RetryUtils.retry block, a lookup's LookupExtractorFactory.start() returning false throws an IllegalStateException, causing the retry policy to re-attempt loading the lookup until retries are exhausted.

Source

Thrown at server/src/main/java/org/apache/druid/query/lookup/LookupReferencesManager.java:656

    @Override
    public void handle(Map<String, LookupExtractorFactoryContainer> lookupMap, LookupReferencesManager manager)
        throws Exception
    {
      LookupExtractorFactoryContainer old = lookupMap.get(lookupName);
      if (old != null && !lookupExtractorFactoryContainer.replaces(old)) {
        LOG.warn(
            "got notice to load lookup [%s] that can't replace existing [%s].",
            lookupExtractorFactoryContainer,
            old
        );
        return;
      }

      RetryUtils.retry(
          () -> {
            if (!lookupExtractorFactoryContainer.getLookupExtractorFactory().start()) {
              throw new ISE(
                  "start method returned false for lookup [%s]:[%s]",
                  lookupName,
                  lookupExtractorFactoryContainer
              );
            }
            return null;
          },
          e -> true,
          startRetries
      );
      /*
       if new container is initailized then add it to manager to start serving immediately.
       if old container is null then it is fresh load, we can skip waiting for initialization and add the container to registry first. Esp for MSQ workers.
       */
      if (old == null || lookupExtractorFactoryContainer.getLookupExtractorFactory().isInitialized()) {
        old = lookupMap.put(lookupName, lookupExtractorFactoryContainer);
        LOG.debug("Loaded lookup [%s] with spec [%s].", lookupName, lookupExtractorFactoryContainer);
        manager.dropContainer(old, lookupName);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Enable/inspect factory start() logging to see why it returns false.
  2. Fix the underlying connectivity or spec problem so start() can succeed.
  3. Increase lookup start retry settings (lookupStartRetries / RetryUtils config) for known-flaky sources.
  4. Verify the lookup's external dependency is healthy and reachable from the Druid node.

Example fix

// before: transient failing start
{"type":"kafkaLookup",...} // kafka down -> start() false
// after: add retry budget via lookup config
// POST lookup with lookupStartRetries configured, or fix kafka connectivity first
Defensive patterns

Strategy: retry

Validate before calling

// probe the external dependency before issuing a load notice
if (!isReachable(lookupSpec.getConnectorHost(), lookupSpec.getConnectorPort())) { delayLoadNotice(lookupSpec); }

Try / catch

try { manager.add(name, container); } catch (Exception e) { /* handle() retries internally; surface final failure */ LOG.error("lookup %s start failed after retries", name, e); alertOps(name); }

Prevention

When it happens

Trigger: A LoadNotice is handled and the factory's start() returns false (soft failure, e.g., external data source not yet reachable); retries continue until start() succeeds or retry limits are hit.

Common situations: Transient network outages to Kafka/Redis/JDBC sources during broker startup; wrong lookup spec credentials; prolonged dependency unavailability causing final failure after retries.

Related errors


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