karatelabs/karate · warning

no time left to stop

Error message

no time left to stop {}

What it means

KarateLifecycle.stopBounded() attempts to stop a registered Stoppable (server, mock, background process) within a shutdown time budget. If the budget is zero or negative — i.e. the overall shutdown deadline was already exhausted before this stoppable was reached — it logs this warning, skips stopping entirely, and returns StopResult with Outcome.TIMED_OUT. The resource is left running (or leaked) because the shutdown sequence has no time left to wait for a graceful stop.

Solutions

  1. Increase the shutdown time budget / timeout configuration for KarateLifecycle so there is time left when each stoppable is processed
  2. Reduce the number of concurrently registered background resources, or stop them explicitly (and promptly) in test teardown before the global shutdown runs
  3. Check logs for earlier 'timed out stopping' warnings to find the slow resource and fix or shorten its stop time
  4. If the resource must be stopped, stop it directly via its own handle instead of relying on lifecycle batch shutdown

Example fix

// before: many slow mocks registered, budget exhausted by teardown
// after: stop heavy resources explicitly first
MyMock mock = MyMock.start(8080);
// test ...
mock.stop(); // free the shutdown budget early
karateLifecycle.stop(); // remaining stoppables still have time
Defensive patterns

Strategy: validation

Validate before calling

// before shutdown, ensure budget is sane
if (remainingBudgetNanos <= 0) { karate.warn('no shutdown budget left; stopping resources explicitly'); }

Prevention

When it happens

Trigger: Calling KarateLifecycle.stop() (or server/mock shutdown) with a total shutdown budget that was already consumed by earlier stoppables, so budgetNanos <= 0 when this particular Stoppable is processed. Also triggered by explicitly passing a zero/negative budget into stopBounded().

Common situations: Suites registering many background mocks/servers each consuming the shutdown budget; a slow-to-stop resource earlier in the registry eating the whole deadline; environments (CI containers, slow disks) where graceful stops take longer than configured; very small configured shutdown timeout.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/common/KarateLifecycle.java:357

                future.complete(summary);
            }
        }
        synchronized (LOCK) {
            return List.copyOf(results);
        }
    }

    /**
     * Run one {@code stop()} on a worker so it can be abandoned, and report the outcome. A worker
     * that ignores its interrupt is left running — its thread is a daemon, so it cannot hold up
     * JVM exit.
     */
    private static StopResult stopBounded(Stoppable stoppable, long budgetNanos) {
        String name = name(stoppable);
        String kind = kind(stoppable);
        long start = System.nanoTime();
        if (budgetNanos <= 0) {
            logger.warn("no time left to stop {}", name);
            return new StopResult(name, kind, Outcome.TIMED_OUT, Duration.ZERO);
        }
        logger.debug("stopping {} [{}]", name, kind);
        Future<?> future = pool().submit(() -> {
            SHUTDOWN_THREAD.set(true);
            try {
                stoppable.stop();
            } finally {
                SHUTDOWN_THREAD.remove();
            }
        });
        Outcome outcome;
        try {
            future.get(budgetNanos, TimeUnit.NANOSECONDS);
            outcome = Outcome.STOPPED;
        } catch (TimeoutException e) {
            future.cancel(true);
            outcome = Outcome.TIMED_OUT;

View on GitHub (pinned to a22eb90246)