karatelabs/karate · warning

Driver failed post-reset liveness probe, will discard

Error message

Driver failed post-reset liveness probe, will discard

What it means

After resetDriver() succeeds (setUrl to about:blank returned), the provider runs a bounded liveness probe via driver.isResponsive(). A driver can pass about:blank (local, no network) but still hang on real http:// navigations; failing the probe means the pool discards it rather than handing a degraded driver to the next scenario.

Solutions

  1. None needed — the pool discards the driver and creates a replacement
  2. If recurring, restart the browser process between suites or cap pool lifetime (recycle after N scenarios)
  3. Investigate scenarios that switch tabs/close targets before finishing, which wedge the shared page target
Defensive patterns

Strategy: retry

Validate before calling

// after acquiring, confirm real readiness beyond about:blank
driver.setUrl(baseUrl); // small cheap page
if (!driver.isResponsive()) { /* request replacement */ }

Prevention

When it happens

Trigger: driver.isResponsive() returns false immediately after a successful reset when the driver is re-borrowed from the pool (takeHealthyFromPool / waitForDriver path).

Common situations: Chrome wedged after tab-switch scenarios (network-facing navigation hangs while about:blank still works); compositor/paint stalls that an eval probe catches; renderer near-OOM.

Related errors


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

Appendix: source

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

            driver.clearCookies();
            // Barrier on readiness before reuse: setUrl("about:blank") returns early
            // (about: URLs skip waitForPageLoad), so the fresh execution context may
            // still be settling. waitUntilReady() blocks until it is live so the next
            // scenario's first call never races a not-yet-ready context. No-op on
            // backends that establish readiness synchronously.
            driver.waitUntilReady();
        } catch (Exception e) {
            // Reset itself failed — channel is already sick (setUrl timeout, websocket closed, etc.)
            logger.warn("Error resetting driver state, will discard: {}", e.getMessage());
            return false;
        }
        // Post-reset liveness probe. setUrl("about:blank") can succeed on a driver that
        // will still hang on the next http:// navigation (seen after tab-switch.feature —
        // about:blank is local so Chrome handles it even when network-facing navigation
        // is stuck). A bounded Runtime.evaluate catches the degraded state before we
        // return the driver to the pool.
        if (!driver.isResponsive()) {
            logger.warn("Driver failed post-reset liveness probe, will discard");
            return false;
        }
        return true;
    }

    /**
     * Create a new driver from config.
     * Subclasses should override for custom driver creation (e.g., Testcontainers).
     * <p>
     * With no {@code webSocketUrl} each pooled driver launches its own browser process,
     * so slots are isolated by construction. Against a SHARED browser the isolation has
     * to be asked for: a browser-level endpoint gets each slot its own incognito context
     * via {@link CdpDriver#connectNewContext}, because pooled slots sharing one browser
     * context share its cookie jar, and the per-acquire {@code clearCookies()} in
     * {@link #resetDriver} is context-wide — one slot resetting would wipe the cookies of
     * every other slot mid-scenario.
     * </p>
     * <p>

View on GitHub (pinned to a22eb90246)