alibaba/druid · error · IllegalArgumentException

maxActive less than minIdle, {} < {}

Error message

maxActive less than minIdle, {} < {}

What it means

IllegalArgumentException thrown while loading pool sizing from a Properties map (configFromProperties path) when the resolved maxActive is less than the resolved minIdle. Druid derives compareMaxActive/compareMinIdle from the properties (falling back to current field values) and rejects an inverted sizing before applying it.

Source

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

                    LOG.info("password changed");
                }
                incrementUserPasswordVersion();
            }

            {
                Integer initialSize = DruidDataSourceUtils.getPropertyInt(properties, "druid.initialSize");
                if (initialSize != null) {
                    this.initialSize = initialSize;
                }
            }

            Integer maxActive = DruidDataSourceUtils.getPropertyInt(properties, "druid.maxActive");
            Integer minIdle = DruidDataSourceUtils.getPropertyInt(properties, "druid.minIdle");
            if (maxActive != null || minIdle != null) {
                int compareMaxActive = maxActive != null ? maxActive.intValue() : this.maxActive;
                int compareMinIdle = minIdle != null ? minIdle.intValue() : this.minIdle;
                if (compareMaxActive < compareMinIdle) {
                    throw new IllegalArgumentException("maxActive less than minIdle, " + compareMaxActive + " < " + compareMinIdle);
                }
            }
            if (maxActive != null) {
                this.maxActive = maxActive;
            }
            if (minIdle != null) {
                this.minIdle = minIdle;
            }

            DruidDataSourceUtils.configFromProperties(this, properties);
        } finally {
            lock.unlock();
        }

        int replaceCount = 0;
        // replace older version urlUserPassword Connection
        while ((hasOlderVersionUrlUserPasswordConnection())) {
            try {

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Make druid.maxActive >= druid.minIdle in your properties/source.
  2. If only one is overridden, ensure the default for the other is not larger.
  3. Audit the full set of druid.* properties loaded (log them at startup) to find the conflicting override.

Example fix

# before
druid.maxActive=8
druid.minIdle=10
# after
druid.maxActive=20
druid.minIdle=5
Defensive patterns

Strategy: validation

Validate before calling

int max = props.getProperty("druid.maxActive") != null
    ? Integer.parseInt(props.getProperty("druid.maxActive")) : currentMax;
int min = props.getProperty("druid.minIdle") != null
    ? Integer.parseInt(props.getProperty("druid.minIdle")) : currentMin;
if (max < min) {
    throw new IllegalArgumentException("druid.maxActive=" + max + " must be >= druid.minIdle=" + min);
}

Prevention

When it happens

Trigger: Properties containing druid.maxActive and/or druid.minIdle where the effective maxActive < effective minIdle. The check at line 296 throws before any field is mutated.

Common situations: A properties file / System properties overriding only one of the two (e.g. druid.minIdle=10 left in place while druid.maxActive=8 is applied); copying config between environments with different pool sizes; unit misconfiguration.

Related errors


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