apache/druid · error · IllegalStateException
Already closed
Error message
Already closed
What it means
CloseableResourceHolder wraps a lazily-created or shared resource that becomes null once closed. get() refuses to return after close() so callers never use a freed resource, throwing ISE('Already closed').
Solutions
- Obtain the resource before close() and keep your own reference
- Fix lifecycle ordering so consumers stop before the holder is closed
- Guard with isAvailable()/null-check semantics via the holder API if offered
- Do not cache the holder across shutdown boundaries
Example fix
// before holder.close(); Resource r = holder.get(); // ISE // after Resource r = holder.get(); holder.close();
Defensive patterns
Strategy: type-guard
Validate before calling
// acquire the resource before close T res = holder.get(); // then use res after close only if you kept this reference
Type guard
boolean usable = (holder != null); // then call get() before close(); after close(), get() throws by design // prefer: T res = holder.get(); /* before close */
Try / catch
try {
T res = holder.get();
} catch (ISE e) {
if ("Already closed".equals(e.getMessage())) { /* holder was closed; reacquire or skip */ }
else throw e;
} Prevention
- Hold your own reference obtained before close()
- Order shutdown so consumers stop before the holder closes
- Avoid caching the holder past lifecycle boundaries
When it happens
Trigger: Calling get() on the holder after close() has been invoked (e.g. using the holder's resource after a service's lifecycle close, or a double-close followed by use).
Common situations: Extension/service shutdown ordering where a component still holds the holder and fetches the resource during teardown; caching the holder in a longer-lived object.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Already closed
- Already shut down, not starting again
- Already started.
- Already started
- Already started, not starting again
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ea520ce7fdf70738.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/collections/CloseableResourceHolder.java:46
public class CloseableResourceHolder<T extends Closeable> implements ResourceHolder<T>
{
private final AtomicReference<T> resource;
/**
* Use {@link ResourceHolder#fromCloseable}.
*/
CloseableResourceHolder(T resource)
{
this.resource = new AtomicReference<>(Preconditions.checkNotNull(resource, "resource"));
}
@Override
public T get()
{
final T retVal = resource.get();
if (retVal == null) {
throw new ISE("Already closed");
}
return retVal;
}
@Override
public void close()
{
final T oldResource = resource.getAndSet(null);
CloseableUtils.closeAndWrapExceptions(oldResource);
}
}
View on GitHub (pinned to 9b90983fd2)