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

  1. Re-add or re-register the lookup with the given id, then retry
  2. Ensure the lookup is not closed before calling unapply; check lifecycle ordering in your code
  3. 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

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


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