karatelabs/karate · warning
Error closing driver
Error message
Error closing driver: {} What it means
closeDriverQuietly() attempts driver.quit() (only if not already terminated) and swallows any exception, logging this warning with e.getMessage(). It is a best-effort cleanup used when discarding dead or excess drivers, so the warning indicates quit failed but execution continues.
Solutions
- Check for leftover browser processes and clean them up (kill stale chrome between CI runs)
- Verify the browser/CDP versions match the driver expectations
- If the message is 'already closed' style, it is benign — filter or downgrade the log
- Ensure process killing (driver.process kill) works on the platform; some CI containers need extra privileges
Defensive patterns
Strategy: fallback
Validate before calling
if (!driver.isTerminated()) { /* safe to quit */ } Type guard
boolean quittable = d -> d != null && !d.isTerminated();
Try / catch
try { if (!driver.isTerminated()) driver.quit(); } catch (Exception e) { /* already gone */ } Prevention
- Kill leftover chrome processes between CI runs
- Match browser/CDP versions to the driver build
- Ignore benign 'already closed' messages in log triage
When it happens
Trigger: driver.quit() throwing during pool discard — e.g. websocket already closed, CDP call timing out on a crashed browser, or the process already gone so the quit RPC fails.
Common situations: Browser killed externally (OOM, SIGKILL) while pooled; CDP channel broken mid-teardown; zombie chrome process lingering after a failed quit.
Related errors
- Driver failed liveness probe on release, discarding instead…
- Error resetting driver state, will discard
- browser did not return a browserContextId
- browser did not return a targetId for context
- CDP connection failed readiness check
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/2c5f0caa62c85d7b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/PooledDriverProvider.java:451
return CdpDriver.start(options);
}
if (wsUrl.contains("/devtools/browser/")) {
return CdpDriver.connectNewContext(wsUrl, options);
}
if (poolSize > 1) {
logger.warn("pool size {} but webSocketUrl names a single page — all slots will drive the SAME tab."
+ " Pass a browser-level endpoint (see /json/version) for isolated slots: {}", poolSize, wsUrl);
}
return CdpDriver.connect(wsUrl, options);
}
private void closeDriverQuietly(Driver driver) {
try {
if (!driver.isTerminated()) {
driver.quit();
}
} catch (Exception e) {
logger.warn("Error closing driver: {}", e.getMessage());
}
}
/**
* Get current pool size (may be -1 if not yet initialized).
*/
public int getPoolSize() {
return poolSize;
}
/**
* Get current pool statistics for monitoring.
*/
public String getStats() {
return String.format("PooledDriverProvider[size=%d, created=%d, available=%d, assigned=%d]",
poolSize, createdCount.get(),
availableDrivers != null ? availableDrivers.size() : 0,
assignedDrivers.size());View on GitHub (pinned to a22eb90246)