apache/druid · error · IllegalStateException
pollingLookup id [%s] is closed
Error message
pollingLookup id [%s] is closed
What it means
PollingLookup.unapply() (reverse lookup by value) requires the same CacheRefKeeper that apply() uses. If the keeper reference is null the lookup has been closed, and unapply throws an ISE naming the lookup id. It mirrors the apply() guard so reverse mapping cannot run against a torn-down cache.
Source
Thrown at extensions-core/lookups-cached-single/src/main/java/org/apache/druid/server/lookup/PollingLookup.java:145
return (String) cache.get(key);
}
finally {
if (cache != null) {
cacheRefKeeper.doneWithIt();
}
}
}
@Override
public List<String> unapply(@Nullable final String value)
{
if (value == null) {
return Collections.emptyList();
}
CacheRefKeeper cacheRefKeeper = refOfCacheKeeper.get();
if (cacheRefKeeper == null) {
throw new ISE("pollingLookup id [%s] is closed", id);
}
PollingCache cache = cacheRefKeeper.getAndIncrementRef();
try {
if (cache == null) {
// it must've been closed after swapping while I was getting it. Try again.
return this.unapply(value);
}
return cache.getKeys(value);
}
finally {
if (cache != null) {
cacheRefKeeper.doneWithIt();
}
}
}
@Override
public boolean supportsAsMap()View on GitHub (pinned to 9b90983fd2)
Solutions
- Re-add or re-register the lookup with the given id, then retry
- Ensure the lookup is not closed before calling unapply; check lifecycle ordering in your code
- Retry the query after lookup manager synchronization completes
Example fix
// before
List<String> keys = pollingLookup.unapply(value);
// after
List<String> keys = pollingLookup.isOpen()
? pollingLookup.unapply(value)
: Collections.emptyList(); Defensive patterns
Strategy: try-catch
Validate before calling
if (!pollingLookup.isOpen()) { throw new IllegalStateException("lookup " + id + " not available for reverse lookup"); } Type guard
boolean canUnapply(PollingLookup l) { return l != null && l.isOpen(); } Try / catch
try { return lookup.unapply(value); } catch (IllegalStateException e) { log.warn("lookup closed: {}", e.getMessage()); return Collections.emptyList(); } Prevention
- Track lookup lifecycle events so code stops using a lookup once closed
- Synchronize lookup usage with lookup manager refresh notifications
- Verify the lookup id still exists in cluster lookup config before reverse lookups
When it happens
Trigger: Calling unapply(value) after close(), or during a concurrent lookup update/close while a query performs reverse lookup.
Common situations: Queries using lookup extraction in reverse mode against a lookup that was deleted/refreshed mid-query; holding a lookup reference past its lifecycle in custom extraction code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cache reference is null
- can't start.
- can't start.
- can't stop.
- Invalid operation - KinesisRecordSupplier has already been c
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/65ea8e9767686c1c.
Report an issue: GitHub.