karatelabs/karate · warning
retry started: (max attempts, ms interval)
Error message
retry started: {} (max {} attempts, {}ms interval) What it means
This is a WARN log emitted by the CDP driver's centralized retry helper when it exhausts the first (non-retry) condition check and begins polling a condition. It indicates a condition passed to the retry mechanism (element wait, page readiness, etc.) did not hold on the first attempt, so Karate is entering a sleep-and-recheck loop up to maxAttempts with the given interval. It is diagnostic, not thrown: the condition may still succeed or fail later.
Solutions
- Treat as diagnostic; wait for the subsequent 'retry succeeded' or 'retry FAILED' log to know the outcome.
- If retries consistently trigger, increase waits/timeouts in the test or reduce page slowness rather than polling.
- If it never succeeds, inspect the condition's target (selector, URL, frame) — the retry loop is only masking a real failure.
- Check the thread is not being interrupted; interrupted threads abort retries early.
Defensive patterns
Strategy: retry
Prevention
- Expect this log on slow pages; pre-warm the app or add explicit waits before actions.
- Keep an eye on whether retries consistently fire — repeated lines indicate systematic slowness.
- Ensure test threads are not interrupted (shutdown hooks, executor cancels) so retries aren't aborted.
When it happens
Trigger: Any call into CdpDriver's public retry path where the Supplier<Boolean> condition returns false or null on the very first evaluation — e.g. waiting for a DOM element, navigation state, or driver readiness that is not yet satisfied.
Common situations: Slow page loads or SPA hydration on first navigation; flaky CI environments where Chrome is slow to attach; waiting on async UI rendered after a click; an overly short initial condition check.
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.
Related errors
- retry succeeded after
- retry attempt / failed for
- retry FAILED after attempts: |
- no frame at index: after retries
- locator is not a frame
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/abc5331fc20f44ec.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:4270
/**
* Centralized retry mechanism with warning logging.
* Use this for all retry operations to ensure consistent behavior and logging.
*
* @param description what we're waiting for (used in warning logs)
* @param condition returns true when the condition is met
* @param maxAttempts maximum number of retry attempts (0 means try once)
* @param interval milliseconds between retries
* @return true if condition was met, false if all retries exhausted
*/
private boolean retry(String description, Supplier<Boolean> condition, int maxAttempts, int interval) {
// First attempt (not a retry)
if (Boolean.TRUE.equals(condition.get())) {
return true;
}
// Log that we're starting retries (helps diagnose flaky tests)
logger.warn("retry started: {} (max {} attempts, {}ms interval)", description, maxAttempts, interval);
// Retry loop
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
// Abort on interruption instead of degrading into a busy spin: sleep()
// preserves the interrupt flag, so every later sleep would return
// instantly and the remaining attempts would hammer CDP back-to-back.
if (Thread.currentThread().isInterrupted()) {
logger.warn("retry aborted (thread interrupted): {}", description);
return false;
}
sleep(interval);
if (Boolean.TRUE.equals(condition.get())) {
logger.warn("retry succeeded after {} attempt(s): {}", attempt, description);
return true;
}
logger.warn("retry attempt {}/{} failed for: {}", attempt, maxAttempts, description);
}
View on GitHub (pinned to a22eb90246)