t8y2/dbx · warning · SQLException

Interrupted while waiting for the JDBC physical connection b

Error message

Interrupted while waiting for the JDBC physical connection budget

What it means

Thrown when the thread waiting to acquire a physical connection budget permit (semaphore limiting concurrent physical connections) is interrupted. The interrupt flag is restored and the interruption is wrapped in a SQLException. It indicates caller-side cancellation, not pool exhaustion.

Source

Thrown at agents/common/src/main/java/com/dbx/agent/JdbcConnectionPoolRegistry.java:1683

    }

    private static final class PhysicalConnectionBudget {
        private final int maximum;
        private final Semaphore permits;

        private PhysicalConnectionBudget(int maximum) {
            this.maximum = maximum;
            this.permits = new Semaphore(maximum, true);
        }

        private void acquire(OperationDeadline deadline) throws SQLException {
            try {
                if (permits.tryAcquire(deadline.remainingNanos(), TimeUnit.NANOSECONDS)) {
                    return;
                }
            } catch (InterruptedException error) {
                Thread.currentThread().interrupt();
                throw new SQLException("Interrupted while waiting for the JDBC physical connection budget", error);
            }
            throw new PhysicalConnectionLimitException(maximum);
        }

        private Connection wrap(
            Connection connection,
            PhysicalConnectionCloser physicalConnectionCloser,
            ConnectionFactoryDataSource factoryDataSource,
            long closeTimeoutMillis,
            ConnectionFactoryDataSource.HikariSetupAttempt setupAttempt
        ) {
            AtomicBoolean released = new AtomicBoolean();
            return (Connection) Proxy.newProxyInstance(
                JdbcConnectionPoolRegistry.class.getClassLoader(),
                new Class<?>[] {Connection.class, HikariSetupTrackedConnection.class},
                (proxy, method, arguments) -> {
                    if ("completeHikariSetup".equals(method.getName()) && method.getParameterCount() == 0) {
                        setupAttempt.completeSuccessfully();

View on GitHub (pinned to c0390bff16)

Solutions

  1. Treat it as cancellation: check the InterruptedException cause and unwind gracefully
  2. Avoid interrupting pool worker threads during shutdown; drain/await outstanding checkouts first
  3. Increase maximum physical connections to reduce time threads spend blocked on permits
  4. Use the deadline mechanism (timeout) instead of interrupt() to bound waiting

Example fix

// before
exec.shutdownNow();
// after
pool.drain(timeout); // let in-flight checkouts finish before shutdownNow
exec.shutdownNow();
Defensive patterns

Strategy: try-catch

Validate before calling

if (Thread.currentThread().isInterrupted()) {
    throw new CancellationException("skip physical connect: already interrupted");
}

Type guard

static boolean isBudgetInterruption(SQLException e) {
    return e.getCause() instanceof InterruptedException
        && e.getMessage() != null
        && e.getMessage().contains("physical connection budget");
}

Try / catch

try {
    conn = pool.checkout();
} catch (SQLException e) {
    if (isBudgetInterruption(e)) {
        Thread.currentThread().interrupt();
        throw new CancellationException(e);
    }
    throw e;
}

Prevention

When it happens

Trigger: All physical-connection permits are held and the caller blocks in permits.tryAcquire(deadline) inside the physical-connect path, then another thread interrupts it (executor.shutdownNow(), request cancellation, shutdown hook).

Common situations: Graceful shutdown while the pool is at its physical connection limit; cancelled HTTP requests whose worker threads were queued waiting for connection budget; timeouts implemented via thread interruption.

Related errors


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