alibaba/druid · error · SQLException

can not restart, activeCount not zero. {}

Error message

can not restart, activeCount not zero. {}

What it means

SQLException thrown by restart() / restart(Properties) when activeCount > 0, i.e. when connections are still checked out to application code. Restart closes and reinitializes the pool, which would orphan in-flight transactions, so Druid refuses to restart while any connection is in use.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java:440

        this.resetStatEnable = resetStatEnable;
        if (dataSourceStat != null) {
            dataSourceStat.setResetStatEnable(resetStatEnable);
        }
    }

    public long getDiscardCount() {
        return discardCount;
    }

    public void restart() throws SQLException {
        this.restart(null);
    }

    public void restart(Properties properties) throws SQLException {
        lock.lock();
        try {
            if (activeCount > 0) {
                throw new SQLException("can not restart, activeCount not zero. " + activeCount);
            }
            if (LOG.isInfoEnabled()) {
                LOG.info("{dataSource-" + this.getID() + "} restart");
            }

            this.close();
            this.resetStat();
            this.inited = false;
            this.enable = true;
            this.closed = false;

            if (properties != null) {
                DruidDataSourceUtils.configFromProperties(this, properties);
            }
        } finally {
            lock.unlock();
        }
    }

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Drain active connections first: stop incoming work, wait for activeCount to reach 0 (dataSource.getActiveCount()), then restart.
  2. Fix connection leaks so borrowed connections are always returned.
  3. If draining is not possible, close() the datasource instead of restart() and create a new one.
  4. Monitor getActiveCount() and only call restart() once it reports 0.

Example fix

// before
while (dataSource.getActiveCount() > 0) { /* busy wait */ }
dataSource.restart();
// after
// stop accepting work, then:
long deadline = System.currentTimeMillis() + 30_000;
while (dataSource.getActiveCount() > 0 && System.currentTimeMillis() < deadline) {
    Thread.sleep(200);
}
if (dataSource.getActiveCount() == 0) {
    dataSource.restart();
} else {
    throw new IllegalStateException("cannot drain active connections");
}
Defensive patterns

Strategy: validation

Validate before calling

if (dataSource.getActiveCount() > 0) {
    throw new IllegalStateException("cannot restart: " + dataSource.getActiveCount()
        + " active connections still borrowed; drain first");
}
dataSource.restart();

Try / catch

try {
    dataSource.restart();
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("can not restart")) {
        LOG.warn("restart blocked by active connections: {}", e.getMessage());
        // back off and retry after draining
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling dataSource.restart() while one or more connections borrowed via getConnection() have not been returned (activeCount > 0). The guard at line 439 throws.

Common situations: Restarting the datasource during request handling; a connection leak (unclosed Connection/Statement/ResultSet) keeps activeCount non-zero; long-running queries/transactions in flight; restart invoked from a management endpoint under load.

Related errors


AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14). Data as JSON: /api/errors/156952840403eac9. Report an issue: GitHub.