karatelabs/karate · critical · DriverException
Failed to start
Error message
Failed to start ${executable}: ${message} What it means
W3cDriver.launch starts the WebDriver process (e.g. chromedriver/geckodriver), then creates a W3C session over HTTP. Any RuntimeException during process start or session creation is wrapped into a DriverException 'Failed to start <executable>: <message>' after killing the process, preserving the underlying cause.
Solutions
- Read the wrapped cause (e.getMessage()) — it names the actual failure
- Verify the configured executable runs: `<executable> --version` and matches the installed browser version
- Check the port is free or let the driver pick a free port
- Confirm the target browser is installed and reachable
- Increase the timeout if the driver binary is slow to boot on CI
Example fix
// before: mismatched driver/browser geckodriver 0.30 with very new Firefox // after upgrade geckodriver to a version matching the installed Firefox
Defensive patterns
Strategy: try-catch
Validate before calling
String v = new ProcessBuilder(executable, "--version").start().getText().trim(); // compare against installed browser version before launching
Try / catch
try {
W3cDriver d = W3cDriver.start(opts);
} catch (DriverException e) {
logger.error("driver launch failed: {} cause: {}", e.getMessage(), e.getCause());
// fix per cause: version mismatch, busy port, missing browser
} Prevention
- Keep WebDriver binary version matched to browser version (use webdriver-manager style tooling)
- Validate the executable path exists and is runnable before launch
- Let the driver choose a free port instead of hardcoding one
- Install the browser itself in CI images, not just the driver
When it happens
Trigger: WebDriver binary missing or not executable; driver process starts but the session endpoint never becomes reachable; session creation POST fails (bad capabilities, protocol mismatch, port already in use); timeout while waiting for the local server.
Common situations: chromedriver version mismatched with installed Chrome; another process holding the chosen port; running chromedriver binary for the wrong OS/arch; missing browser on CI; wrong 'executable' path in config.
Related errors
- exec() needs at least one argument
- CDP connection failed readiness check
- options cannot be null
- chrome failed to start or no page targets available within…
- javascript failed
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/a3e9dda78ed98911.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java:154
ProcessHandle process = ProcessHandle.start(
ProcessBuilder.create()
.args(command)
.redirectErrorStream(true)
.logToContext(false) // don't pollute scenario logs with driver chatter
.build()
);
try {
// Wait for the driver to start accepting connections
waitForPort("localhost", port, opts.getTimeoutDuration().toMillis());
logger.info("{} started on port {}", executable, port);
String baseUrl = "http://localhost:" + port;
W3cSession session = W3cSession.create(baseUrl, opts.buildSessionPayload(), opts.getTimeoutDuration());
return new W3cDriver(session, opts, process);
} catch (RuntimeException e) {
process.close(true);
throw new DriverException("Failed to start " + executable + ": " + e.getMessage(), e);
}
}
/**
* Get the underlying W3C session for direct protocol access.
*/
public W3cSession getSession() {
return session;
}
// ========== CoreDriver Tier 1: Essential Primitives ==========
/**
* Execute JavaScript via W3C executeScript.
*
* <p>Battle-tested pattern from v1 WebDriver: if JS execution fails, sleep once and
* retry before throwing. This handles transient failures that occur when the page is
* still loading or transitioning. The v1 codebase proved this single-retry approachView on GitHub (pinned to a22eb90246)