alibaba/druid · error · IllegalArgumentException

timeBetweenEvictionRunsMillis must > 0

Error message

timeBetweenEvictionRunsMillis must > 0

What it means

setTimeBetweenEvictionRunsMillis rejects any value <= 0, regardless of init state. This interval drives the evictor thread (a negative/zero period cannot schedule the Timer/ScheduledExecutor). There is no advisory path - the exception is unconditional.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java:861

    public int getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    /**
     * @param numTestsPerEvictionRun number of tests per eviction run
     */
    @Deprecated
    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

    public long getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
        if (timeBetweenEvictionRunsMillis <= 0) {
            throw new IllegalArgumentException("timeBetweenEvictionRunsMillis must > 0");
        }

        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public int getMaxWaitThreadCount() {
        return maxWaitThreadCount;
    }

    public void setMaxWaitThreadCount(int maxWaithThreadCount) {
        this.maxWaitThreadCount = maxWaithThreadCount;
    }

    public String getValidationQuery() {
        return validationQuery;
    }

    public void setValidationQuery(String validationQuery) {

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Provide a positive value (typical: 60000ms; must be > 0).
  2. If you intended to disable the evictor, simply do not call the setter / leave the property unset rather than passing 0.
  3. Fix unresolved property placeholders so they do not coerce to 0.

Example fix

// before
// ds.setTimeBetweenEvictionRunsMillis(0); // throws

// after
// ds.setTimeBetweenEvictionRunsMillis(60000);
Defensive patterns

Strategy: validation

Validate before calling

long v = configuredInterval;
if (v <= 0) throw new IllegalArgumentException("timeBetweenEvictionRunsMillis must > 0");
ds.setTimeBetweenEvictionRunsMillis(v);

Try / catch

try {
    ds.setTimeBetweenEvictionRunsMillis(value);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("timeBetweenEvictionRunsMillis must > 0")) {
        // supply a positive value; to disable eviction, omit the call entirely
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling setTimeBetweenEvictionRunsMillis(0) or with a negative value, e.g. from a property source that resolves to 0 when unset.

Common situations: A placeholder (${timeBetweenEvictionRunsMillis}) that resolves to empty/0 because the property was not defined; Spring @Value defaulting to 0; disabling eviction by setting 0 (not supported - to disable, omit the call).

Related errors


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