karatelabs/karate · error · RuntimeException
listen timed out after
Error message
listen timed out after <timeoutMs>ms
What it means
The `listen` keyword pauses the scenario until external code (e.g. a mock server or browser callback) supplies a result via listenResult. If nothing arrives within the configured timeout, the CountDownLatch await expires and the runtime throws "listen timed out after <timeoutMs>ms".
Solutions
- Verify the code paired with listen actually calls `karate.signal(result)` (or the listen server posts the result) and that it is running
- Increase the listen timeout, e.g. `* listen 30000 result` for slow environments
- Check ports/firewalls and callback URLs so the external side can reach the listener; add logging on the callback path
Example fix
// before * listen 5000 token // times out in slow CI // after * listen 60000 token
Defensive patterns
Strategy: try-catch
Try / catch
try { karate.listen(60000, 'token'); } catch (RuntimeException e) { if (e.getMessage().startsWith("listen timed out")) { /* check callback fired / increase timeout */ } throw e; } Prevention
- Pair every listen with code that definitely calls karate.signal(result)
- Start the mock server/listener before the listen step and verify its port is reachable
- Use generous timeouts in CI and add logging on the callback path
When it happens
Trigger: `* listen <timeout> someVariable` where no callback invokes karate.signal(listenKey) / sets the listen result before timeoutMs elapses.
Common situations: OAuth/browser redirect flows where the external service never calls back; mock server not started or listening on the wrong port; async JS in the browser not triggering the result; timeout too short for a slow environment.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- async drain timed out
- HTTP endpoint not available
- Port : not available within timeout
- listen interrupted
- retry failed after attempts:
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/d2ee41db21938279.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java:2482
public void setListenResult(Object result) {
this.listenResult = result;
this.listenLatch.countDown();
}
/**
* Wait for a signal with timeout.
* Returns the signaled result or throws on timeout.
*/
public Object waitForListenResult(long timeoutMs) {
try {
if (listenLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
Object result = listenResult;
// Reset for potential reuse
listenResult = null;
listenLatch = new CountDownLatch(1);
return result;
}
throw new RuntimeException("listen timed out after " + timeoutMs + "ms");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("listen interrupted", e);
}
}
/**
* Get the current listen result without waiting.
*/
public Object getListenResult() {
return listenResult;
}
// ========== Performance Testing (Gatling Integration) ==========
/**
* Check if performance mode is enabled.
* When true, HTTP request timing is reported via PerfHook.View on GitHub (pinned to a22eb90246)