karatelabs/karate · error · RuntimeException
CDP connection failed readiness check
Error message
CDP connection failed readiness check: {message} What it means
After opening the DevTools websocket, waitForReady sends a probe CDP command (Browser.getVersion). Any exception during that handshake is wrapped as 'CDP connection failed readiness check: <cause message>'. The connection was established but the browser did not answer the readiness probe correctly.
Solutions
- Read the wrapped cause message (e.getMessage()) — it names the real failure (connection reset, CDP error, etc.) and fix that
- Verify the browser executable path launches a supported Chrome/Chromium/Edge version
- Kill stale processes holding the DevTools port and retry
- In containers, add required flags (e.g. --no-sandbox) and ensure shared memory/deps are present
- Disable proxies for localhost so the DevTools websocket is not intercepted
Example fix
// before: wrong binary
karate.configure("driver", { type: 'chrome', executable: '/usr/bin/chromium-browser' }); // stale wrapper that exits
// after: valid supported binary
karate.configure("driver", { type: 'chrome', executable: '/usr/bin/google-chrome' }); Defensive patterns
Strategy: retry
Validate before calling
// pre-check the DevTools endpoint before connecting
Socket s = new Socket();
boolean ok = s.isConnected(); // after s.connect(new InetSocketAddress("localhost", port), 2000)
s.close(); Type guard
null
Try / catch
try { connect(); }
catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("CDP connection failed readiness check")) {
retryWithBackoff(3, this::connect); // relaunch browser each attempt
} else throw e;
} Prevention
- Verify the browser binary path launches a supported Chrome/Edge
- Kill stale processes on the DevTools port before launching
- Disable proxies for localhost
- Add container flags (--no-sandbox) and check browser version compatibility
When it happens
Trigger: Browser closes or crashes immediately after launch (port raced, wrong executable); wrong websocket endpoint URL; the browser responds with a CDP error to the readiness command; a non-Chrome/unsupported browser on the DevTools port; proxy or firewall interfering with the local DevTools socket.
Common situations: chrome/edge binary path misconfigured so something else listens on the port; browser version mismatch with the driver's CDP expectations; browser exits early in CI containers (missing deps, no sandbox flags); stale browser process occupying the debug port.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- CDP timeout for
- CDP error
- browser did not return a browserContextId
- readyState check exception
- dialog accept failed
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/c0d5873a81fb1a51.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpClient.java:131
/**
* Wait for CDP to be ready by sending a simple command.
* This verifies the WebSocket connection is fully established and CDP is responsive.
*/
private void waitForReady() {
try {
// Use a shorter timeout for readiness check
Duration readyTimeout = defaultTimeout.compareTo(Duration.ofSeconds(10)) > 0
? Duration.ofSeconds(10) : defaultTimeout;
CdpMessage message = new CdpMessage(this, nextId(), "Browser.getVersion");
message.timeout(readyTimeout);
CdpResponse response = send(message);
if (response.isError()) {
logger.warn("CDP readiness check returned error: {}", response.getErrorMessage());
} else {
logger.debug("CDP ready, browser: {}", response.getResult().get("product"));
}
} catch (Exception e) {
throw new RuntimeException("CDP connection failed readiness check: " + e.getMessage(), e);
}
}
private void setupMessageHandler() {
ws.onMessage(frame -> {
if (frame.isText()) {
handleMessage(frame.getText());
}
});
ws.onClose(() -> {
// Complete all pending futures exceptionally
for (PendingRequest pr : pending.values()) {
pr.future.completeExceptionally(
new WsException(WsException.Type.CONNECTION_CLOSED, "websocket closed"));
}
pending.clear();
});
ws.onError(error -> {View on GitHub (pinned to a22eb90246)