alibaba/druid · error · SQLException
maxEvictableIdleTimeMillis must be grater than minEvictableI
Error message
maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis
What it means
SQLException thrown during init() when maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis. The evictor uses min as the soft floor and max as the hard ceiling for idle connection eviction; an inverted relationship (max < min) would make eviction logic contradictory, so it is rejected. (Note the message typo 'grater'.)
Source
Thrown at core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java:735
if (maxActive <= 0) {
throw new IllegalArgumentException("illegal maxActive " + maxActive);
}
if (maxActive < minIdle) {
throw new IllegalArgumentException("illegal maxActive " + maxActive);
}
if (getInitialSize() > maxActive) {
throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActive " + maxActive);
}
if (timeBetweenLogStatsMillis > 0 && useGlobalDataSourceStat) {
throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGlobalDataSourceStat=true");
}
if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) {
throw new SQLException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis");
}
if (keepAlive && keepAliveBetweenTimeMillis <= timeBetweenEvictionRunsMillis) {
throw new SQLException("keepAliveBetweenTimeMillis must be greater than timeBetweenEvictionRunsMillis");
}
if (this.driverClass != null) {
this.driverClass = driverClass.trim();
}
initFromSPIServiceLoader();
resolveDriver();
initCheck();
this.netTimeoutExecutor = new SynchronousExecutor();
View on GitHub (pinned to fa8dc99126)
Solutions
- Set maxEvictableIdleTimeMillis >= minEvictableIdleTimeMillis (typically max several times larger than min).
- Double-check units: both are milliseconds in Druid.
- Leave them at defaults unless you have a measured eviction need.
Example fix
// before dataSource.setMinEvictableIdleTimeMillis(600_000); // 10 min dataSource.setMaxEvictableIdleTimeMillis(300_000); // 5 min -> throws // after dataSource.setMinEvictableIdleTimeMillis(300_000); // 5 min dataSource.setMaxEvictableIdleTimeMillis(900_000); // 15 min
Defensive patterns
Strategy: validation
Validate before calling
if (dataSource.getMaxEvictableIdleTimeMillis() < dataSource.getMinEvictableIdleTimeMillis()) {
throw new IllegalStateException("maxEvictableIdleTimeMillis ("
+ dataSource.getMaxEvictableIdleTimeMillis()
+ ") must be >= minEvictableIdleTimeMillis ("
+ dataSource.getMinEvictableIdleTimeMillis() + ")");
} Prevention
- Keep maxEvictableIdleTimeMillis several times larger than min.
- Remember all eviction timers are milliseconds.
- Leave defaults unless you have measured eviction needs.
When it happens
Trigger: init() with maxEvictableIdleTimeMillis strictly less than minEvictableIdleTimeMillis. The check at line 734 throws.
Common situations: Manually tuning eviction timers and swapping the two values; copying timings from another pool with different semantics; unit confusion (seconds vs milliseconds).
Related errors
- keepAliveBetweenTimeMillis must be greater than timeBetweenE
- illegal maxActive {}
- illegal initialSize {}, maxActive {}
- timeBetweenLogStatsMillis not support useGlobalDataSourceSta
- maxEvictableIdleTimeMillis must be grater than minEvictableI
AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14).
Data as JSON: /api/errors/9ecd603839f59833.
Report an issue: GitHub.