t8y2/dbx · error · IllegalStateException
JDBC connection pool registry is closed
Error message
JDBC connection pool registry is closed
What it means
JdbcConnectionPoolRegistry.borrow() refuses to hand out pool leases once the registry has been closed (close() sets the closed flag, shuts down the Hikari pools, executors, and budget). Any borrow() call after close() throws IllegalStateException("JDBC connection pool registry is closed") because the internal executors and pools no longer exist.
Source
Thrown at agents/common/src/main/java/com/dbx/agent/JdbcConnectionPoolRegistry.java:95
this.checkoutExecutor = new JdbcCheckoutExecutor(
settings.globalMaximumPhysicalConnections,
connectionReleaseExecutor
);
}
Lease borrow(String identity, ConnectionFactory connectionFactory) throws Exception {
return borrow(identity, JdbcSessionRole.WORKLOAD, null, connectionFactory);
}
Lease borrow(String identity, JdbcSessionRole role, ConnectionFactory connectionFactory) throws Exception {
return borrow(identity, role, null, connectionFactory);
}
Lease borrow(String identity, JdbcSessionRole role, String connectionTestQuery, ConnectionFactory connectionFactory) throws Exception {
String key = digest(identity);
while (true) {
if (closed.get()) {
throw new IllegalStateException("JDBC connection pool registry is closed");
}
SQLException failure = runtimeFailure.get();
if (failure != null) {
throw AgentRpcError.resource("close", failure);
}
PoolEntry entry;
try {
entry = pools.computeIfAbsent(key, ignored -> createPoolEntry(key, connectionTestQuery, connectionFactory));
} catch (PoolCreationException error) {
throw error.unwrap();
}
try {
return entry.borrow(role);
} catch (PoolRetiredException ignored) {
pools.remove(key, entry);
} catch (AgentRpcError error) {
if (entry.isRetired()) {
pools.remove(key, entry);View on GitHub (pinned to c0390bff16)
Solutions
- Treat the registry as single-use: after close(), create a new JdbcConnectionPoolRegistry for subsequent borrows.
- Serialize lifecycle: stop all producers of borrow() calls (executors, schedulers) before calling close().
- Check a shared closed/isRunning flag (or registry state) before borrowing, and route to a fresh registry if closed.
- Catch IllegalStateException at the borrow site and reinitialize the registry + retry once.
Example fix
// before
Lease lease = registry.borrow(identity, factory);
// after
if (registryClosed) {
registry = new JdbcConnectionPoolRegistry();
registryClosed = false;
}
Lease lease = registry.borrow(identity, factory); Defensive patterns
Strategy: retry
Validate before calling
if (registryClosed) {
registry = new JdbcConnectionPoolRegistry();
registryClosed = false;
} Type guard
static boolean registryUsable(JdbcConnectionPoolRegistry r) {
return r != null && !r.isClosed(); // expose a state flag if not already available
} Try / catch
try {
return registry.borrow(identity, factory);
} catch (IllegalStateException e) {
if (e.getMessage().contains("registry is closed")) {
registry = new JdbcConnectionPoolRegistry();
return registry.borrow(identity, factory);
}
throw e;
} Prevention
- Treat the registry as single-use; recreate rather than reuse after close().
- Shut down all borrow() producers before calling close() in shutdown hooks.
- Centralize registry lifecycle in one owner so close() and borrow() cannot race.
- In tests, build a fresh registry per test instead of closing a shared one.
When it happens
Trigger: Calling borrow(identity, ...) on a registry instance after close() was invoked — e.g. an agent/shutdown hook closed the registry while background tasks or other threads still attempt to acquire connections.
Common situations: Application shutdown closes the registry while in-flight requests still try to borrow; a singleton registry was closed once (e.g. during a reconnect attempt or test teardown) and later reused; double-close race where one thread closes while another borrows.
Related errors
- No active JDBC checkout owns physical connection creation
- JDBC pool registry must be attached before connecting
- JDBC Session was quarantined while waiting for a connection
- Not connected
- Failed to checkout JDBC connection
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/067639d33d7fca46.
Report an issue: GitHub.