apache/druid · error · IllegalStateException

Expected WeakReference, got: %s

Error message

Expected WeakReference, got: %s

What it means

OnHeapNamespaceExtractionCacheManager stores cache ids as WeakReference objects; disposeCache() requires that invariant. If a CacheHandler arrives whose id is not a WeakReference, the manager cannot remove it from its weak-reference collection and throws this ISE, indicating the handler was not created by this manager.

Source

Thrown at extensions-core/lookups-cached-global/src/main/java/org/apache/druid/server/lookup/namespace/cache/OnHeapNamespaceExtractionCacheManager.java:141

  {
    if (cache.getCache() instanceof ImmutableLookupMap) {
      return ((ImmutableLookupMap) cache.getCache()).asLookupExtractor(isOneToOne, cacheKeySupplier);
    } else {
      return new MapLookupExtractor(cache.getCache(), isOneToOne) {
        @Override
        public byte[] getCacheKey()
        {
          return cacheKeySupplier.get();
        }
      };
    }
  }

  @Override
  void disposeCache(CacheHandler cacheHandler)
  {
    if (!(cacheHandler.id instanceof WeakReference)) {
      throw new ISE("Expected WeakReference, got: %s", cacheHandler.id);
    }
    caches.remove(cacheHandler.id);
  }

  @Override
  int cacheCount()
  {
    expungeCollectedCaches();
    return caches.size();
  }

  @Override
  void monitor(ServiceEmitter serviceEmitter)
  {
    long numEntries = 0;
    long heapSizeInBytes = 0;
    expungeCollectedCaches();
    for (WeakReference<Map<String, String>> cacheRef : caches) {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Only dispose CacheHandlers obtained from the same CacheScheduler/manager that created them.
  2. Verify the CacheHandler implementation matches the active namespace extraction cache manager.
  3. If constructing handlers in tests, use manager/scheduler factory methods so ids are WeakReferences.

Example fix

// before
CacheHandler h = new CacheHandler(scheduler, someMap, id); // raw id
onHeapManager.disposeCache(h); // ISE
// after
Entry e = scheduler.schedule(namespace);
scheduler.delete(e); // proper lifecycle, correct id type
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(cacheHandler.id instanceof WeakReference)) { throw new IllegalArgumentException("handler not created by on-heap manager"); }

Type guard

boolean disposable(CacheHandler h) { return h.id instanceof WeakReference; }

Try / catch

try { manager.disposeCache(handler); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Expected WeakReference")) { /* wrong manager; dispose via originating scheduler */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling disposeCache(cacheHandler) with a handler whose id is a plain map or foreign id object — typically a handler built for a different cache manager implementation (e.g. off-heap) or manually constructed.

Common situations: Mixing cache managers (on-heap manager disposing an off-heap CacheHandler); manually constructing CacheHandler with a raw id; classpath mixing of old/new versions of the lookup extension.

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/c77f9ca8476bfb21. Report an issue: GitHub.