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

  1. Treat the registry as single-use: after close(), create a new JdbcConnectionPoolRegistry for subsequent borrows.
  2. Serialize lifecycle: stop all producers of borrow() calls (executors, schedulers) before calling close().
  3. Check a shared closed/isRunning flag (or registry state) before borrowing, and route to a fresh registry if closed.
  4. 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

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


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/067639d33d7fca46. Report an issue: GitHub.