{"record":{"id":"a786b33a8aed4c28","repo":"karatelabs/karate","slug":"chrome-failed-to-start-or-no-page-targets-available-within","errorCode":null,"errorMessage":"chrome failed to start or no page targets available within timeout (${timeout}ms)","messagePattern":"chrome failed to start or no page targets available within timeout \\((.+?)ms\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpLauncher.java","lineNumber":122,"sourceCode":"        List<String> args = buildArgs(executable, port, options);\n        logger.debug(\"launching chrome: {}\", args);\n\n        ProcessHandle process = ProcessHandle.start(\n                ProcessBuilder.create()\n                        .args(args)\n                        .logToContext(false) // don't log browser output to test context\n                        .build()\n        );\n\n        CdpLauncher launcher = new CdpLauncher(process, host, port);\n\n        // Wait for Chrome to be ready AND get WebSocket URL atomically\n        // This avoids a race condition where /json/version returns 200\n        // before any page targets are available\n        launcher.webSocketUrl = launcher.waitForWebSocketUrl(timeout);\n        if (launcher.webSocketUrl == null) {\n            launcher.close();\n            throw new RuntimeException(\"chrome failed to start or no page targets available within timeout (\" + timeout + \"ms)\");\n        }\n\n        logger.info(\"chrome started on port {} with WebSocket: {}\", port, launcher.webSocketUrl);\n        return launcher;\n    }\n\n    /**\n     * Get WebSocket URL from existing browser at host:port.\n     */\n    public static String getWebSocketUrl(String host, int port) {\n        if (host == null || host.isEmpty()) {\n            host = \"localhost\";\n        }\n        if (port <= 0 || port > 65535) {\n            throw new IllegalArgumentException(\"port must be between 1 and 65535\");\n        }\n        return fetchWebSocketUrl(host, port);\n    }","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpLauncher.java#L104-L140","documentation":"After spawning the Chrome process, the launcher polls for a DevTools WebSocket URL. If no page target (and thus no WS endpoint) appears within the timeout, Chrome is closed and this RuntimeException is thrown. It signals the browser process either failed to start or started without exposing usable page targets in time.","triggerScenarios":"Chrome binary exists but crashes on launch (bad flags, missing sandbox permissions, display unavailable); very slow machine where Chrome startup exceeds the timeout; Chrome version whose /json endpoint exposes no page targets within the wait window.","commonSituations":"CI containers without --no-sandbox or without a running X/display; headless Chrome killed by OOM; overly tight custom timeout in driver options; broken Chrome install that exits immediately.","solutions":["Increase the startup timeout in driver options (e.g. timeout setting) and retry","Run Chrome manually with the same flags (check karate.log for the command line) to see why it exits","In containers, ensure headless mode plus --no-sandbox / adequate /dev/shm size","Verify the configured executable actually runs: `<executable> --version`","Check for stale Chrome processes or a port conflict and clean them up"],"exampleFix":"// before (tight timeout on slow CI)\noptions.setTimeout(5000);\n// after\noptions.setTimeout(30000);","handlingStrategy":"retry","validationCode":"Process check = new ProcessBuilder(executable, \"--version\").start();\nif (check.waitFor(5, TimeUnit.SECONDS) && check.exitValue() != 0) {\n    throw new IllegalStateException(\"chrome binary broken\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    CdpLauncher.start(options);\n} catch (RuntimeException e) {\n    // chrome not ready in time — retry with larger timeout\n    options.setTimeout(options.getTimeout() * 2);\n    CdpLauncher.start(options);\n}","preventionTips":["Use generous timeouts on CI (30s+)","Always run headless with --no-sandbox and sufficient /dev/shm in containers","Smoke-test the chrome binary with --version before suite runs","Keep karate.log handy to inspect the exact launch command"],"tags":["browser-launch","timeout","chrome","devtools"],"backgroundTag":"request-timeout","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}