{"record":{"id":"eb8a718907ffab1d","repo":"apache/druid","slug":"no-items-available","errorCode":null,"errorMessage":"No items available","messagePattern":"No items available","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/collections/QueueNonBlockingPool.java","lineNumber":43,"sourceCode":"/**\n * Implementation of {@link NonBlockingPool} based on a pre-created {@link BlockingQueue} that never actually blocks.\n * If the pool is empty when {@link #take()} is called, it throws {@link NoSuchElementException}.\n */\npublic class QueueNonBlockingPool<T> implements NonBlockingPool<T>\n{\n  private final BlockingQueue<T> queue;\n\n  public QueueNonBlockingPool(final BlockingQueue<T> queue)\n  {\n    this.queue = queue;\n  }\n\n  @Override\n  public ResourceHolder<T> take()\n  {\n    final T item = queue.poll();\n    if (item == null) {\n      throw new NoSuchElementException(\"No items available\");\n    }\n\n    return new ReferenceCountingResourceHolder<>(item, () -> queue.add(item));\n  }\n\n  /**\n   * Number of available items.\n   */\n  public int availableCount()\n  {\n    return queue.size();\n  }\n}\n","sourceCodeStart":25,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/collections/QueueNonBlockingPool.java#L25-L57","documentation":"QueueNonBlockingPool.take() never blocks: it polls the backing queue and throws NoSuchElementException when the pool is empty, by design rather than waiting for a resource to be returned. This makes exhaustion an immediate, explicit failure for the caller.","triggerScenarios":"Calling take() when all pooled objects are checked out (holders not yet closed) or when the pool was never populated / closed and drained. Any concurrent burst of take() calls exceeding pool size.","commonSituations":"Resource leaks where holders are not closed in a finally block so objects never return to the pool; pools sized smaller than concurrency; take() after close(); using the pool in a hot path with spikes in demand.","solutions":["Ensure every ResourceHolder from take() is closed in a try/finally (or try-with-resources) so objects return to the pool","Increase the pool size or add backpressure/limit concurrency to match pool capacity","Retry with backoff on NoSuchElementException, or use a blocking structure (ArrayBlockingQueue.take) if waiting is acceptable","Check for double-close or early close of the pool itself"],"exampleFix":"// before\nResourceHolder<T> holder = pool.take(); // NoSuchElementException under load\nuse(holder.get());\nholder.close();\n// after\ntry (ResourceHolder<T> holder = pool.take()) {\n  use(holder.get());\n}","handlingStrategy":"try-catch","validationCode":"if (pool instanceof QueueNonBlockingPool && sizeKnown && outstanding >= sizeKnown) { /* wait or shed load before take() */ }","typeGuard":null,"tryCatchPattern":"try { holder = pool.take(); } catch (NoSuchElementException e) { /* pool exhausted: retry with backoff or shed */ }","preventionTips":["Always close ResourceHolders in try-with-resources/finally","Size pools for peak concurrency and add backpressure","Never call take() after closing the pool"],"tags":["java","pool","resource-exhaustion"],"backgroundTag":"resource-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}