karatelabs/karate · warning

process died while waiting for HTTP

Error message

process died while waiting for HTTP {}

What it means

`PortUtils.waitForHttp` polls an HTTP URL expecting a response, but the `stillAlive` supplier reported the watched process died during the wait. It logs this warning and returns false rather than waiting for an endpoint that can never come up.

Solutions

  1. Read the process output/logs to find the actual exit cause
  2. Verify the URL and port match what the process actually serves
  3. Ensure the process has sufficient memory and valid startup configuration
  4. Fix the underlying startup failure and retry the wait
Defensive patterns

Strategy: retry

Try / catch

if (!PortUtils.waitForHttp(url, 60, 500, proc::isAlive)) {
    // process died before serving: log proc output and exit code
    throw new RuntimeException("process exited before HTTP endpoint " + url + " was ready");
}

Prevention

When it happens

Trigger: Waiting for a child process's HTTP health endpoint via `waitForHttp(url, attempts, intervalMs, process::isAlive)`; the process crashes or exits before serving any HTTP response.

Common situations: Server failing on startup (bad config, missing port); unhandled exception in the app's bootstrap; container OOM-killed during startup; wrong URL/port in the wait call pointing nowhere while the process dies for an unrelated reason.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/process/PortUtils.java:87

            } catch (Exception e) {
                logger.trace("port {}:{} not yet available (attempt {})", host, port, i + 1);
                sleep(intervalMs);
            }
        }
        logger.warn("port {}:{} not available after {} attempts", host, port, attempts);
        return false;
    }

    /**
     * Wait for an HTTP endpoint to return 200.
     */
    public static boolean waitForHttp(String url, int attempts, int intervalMs, BooleanSupplier stillAlive) {
        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(5))
                .build();
        for (int i = 0; i < attempts; i++) {
            if (stillAlive != null && !stillAlive.getAsBoolean()) {
                logger.warn("process died while waiting for HTTP {}", url);
                return false;
            }
            try {
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(url))
                        .timeout(Duration.ofSeconds(5))
                        .GET()
                        .build();
                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
                if (response.statusCode() >= 200 && response.statusCode() < 300) {
                    logger.debug("HTTP {} is available after {} attempts", url, i + 1);
                    return true;
                }
                logger.trace("HTTP {} returned {} (attempt {})", url, response.statusCode(), i + 1);
            } catch (Exception e) {
                logger.trace("HTTP {} not available (attempt {}): {}", url, i + 1, e.getMessage());
            }
            sleep(intervalMs);

View on GitHub (pinned to a22eb90246)