karatelabs/karate · warning

Could not detect pool size, defaulting to 1

Error message

Could not detect pool size, defaulting to 1

What it means

PooledDriverProvider lazily creates its driver pool on first acquire(). It determines the pool size from an explicit config value or by auto-detecting the Suite's threadCount; if neither yields a size >= 1, it logs this warning and falls back to a pool of 1, which serializes all driver acquisition and can slow parallel UI tests.

Solutions

  1. Set the pool size explicitly, e.g. -Dkarate.driver.poolSize=N or the driver pool config option, so auto-detection is unnecessary
  2. Run with Runner / threadCount set (e.g. -T 4 with Maven surefire or Runner.Builder.threadCount) so the Suite auto-detection path works
  3. Verify the config key spelling for pool size in karate-config.js
  4. Accept the pool of 1 only for debugging; for parallel UI suites, size the pool to match threadCount

Example fix

// before: no pool size, no thread count
Runner.path(classpath("ui/features"));
// after: parallel run so pool auto-detects threadCount
Runner.path(classpath("ui/features")).threadCount(4);
Defensive patterns

Strategy: validation

Validate before calling

// before the run, ensure threadCount is set so pool auto-detection works
int threads = suite.getThreadCount();
if (threads < 1) throw new IllegalStateException("set -T / threadCount so the driver pool can be sized");

Type guard

Integer poolSize = System.getProperty("karate.driver.poolSize") != null
    ? Integer.valueOf(System.getProperty("karate.driver.poolSize"))
    : (suite != null && suite.threadCount > 0 ? suite.threadCount : null); // null => pool of 1 warning

Prevention

When it happens

Trigger: acquire() is called and poolSize is still < 1: no maxPoolSize/driver pool-size config option set AND runtime.getFeatureRuntime().getSuite() is null or its threadCount is 0/unset (e.g. driver used outside a normal parallel Suite context).

Common situations: Chrome/chrome-headless drivers used with default options in a Suite whose threadCount was not propagated; driver acquired in a unit-test or embedded runtime without a Suite; pool-size property misspelled so it never gets read.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/78b89a2a8a13fd5b. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/PooledDriverProvider.java:187

    }

    private void ensurePoolInitialized(ScenarioRuntime runtime) {
        if (availableDrivers != null) {
            return;
        }
        synchronized (initLock) {
            if (availableDrivers != null) {
                return;
            }
            // Auto-detect pool size from Suite's threadCount
            if (poolSize < 1 && runtime.getFeatureRuntime() != null
                    && runtime.getFeatureRuntime().getSuite() != null) {
                poolSize = runtime.getFeatureRuntime().getSuite().threadCount;
                logger.info("Auto-detected pool size from Suite: {}", poolSize);
            }
            if (poolSize < 1) {
                poolSize = 1;  // Fallback
                logger.warn("Could not detect pool size, defaulting to 1");
            }
            availableDrivers = new ArrayBlockingQueue<>(poolSize);
        }
    }

    private Driver waitForDriver(Map<String, Object> config, ScenarioRuntime runtime) {
        String scenarioName = runtime.getScenario().getName();
        logger.warn("Pool exhausted for scenario '{}', waiting for available driver... [{}]",
                scenarioName, getStats());
        try {
            Driver driver = availableDrivers.poll(30, TimeUnit.SECONDS);
            if (driver == null) {
                throw new RuntimeException("Timeout waiting for available driver for scenario '"
                        + scenarioName + "' [" + getStats() + "]");
            }
            // If the driver is terminated OR fails reset/liveness, replace it.
            // Same rationale as takeHealthyFromPool — a poisoned driver must not be
            // handed out to the next scenario.

View on GitHub (pinned to a22eb90246)