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
- Enable/inspect factory start() logging to see why it returns false.
- Fix the underlying connectivity or spec problem so start() can succeed.
- Increase lookup start retry settings (lookupStartRetries / RetryUtils config) for known-flaky sources.
- 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
- Keep lookup start retries configured for transient sources
- Monitor external dependencies (Kafka/Redis/JDBC) health
- Log factory.start() false-returns with enough detail
- Gate bulk loads on dependency readiness checks
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
- Failed to start lookup [%s]:[%s]
- Health check failed [%d/%d] for [%s]
- Exception while watching for role[%s], will retry.
- Failed to fetch Avro schema id[%s] from registry. Check if t
- Recoverable exception
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/8cd7066738943fb1.
Report an issue: GitHub.