flowable/flowable-engine · warning

Timeout during shutdown of async job executor. The current r

Error message

Timeout during shutdown of async job executor. The current running jobs could not end within {} seconds after shutdown operation.

What it means

This is a warning emitted by DefaultAsyncTaskExecutor.shutdown when executorService.awaitTermination does not complete within the configured await-termination period. It means some jobs were still running when the async job executor shut down; the JVM then proceeds to shut the executor down (executorService.shutdownNow follows), potentially interrupting those jobs mid-execution. Data consistency is guarded by the job retry/transaction mechanisms, but job progress may be lost.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/async/DefaultAsyncTaskExecutor.java:116

    public void start() {
        if (executorService == null) {
            this.executorService = initializeExecutor();
            this.executorNeedsShutdown = true;
        }
    }

    @Override
    public void shutdown() {
        if (executorService != null && executorNeedsShutdown) {
            // Ask the thread pool to finish and exit
            executorService.shutdown();

            // Waits for the configured time to finish all currently executing jobs
            try {
                long secondsToWaitOnShutdown = configuration.getAwaitTerminationPeriod().getSeconds();
                if (!executorService.awaitTermination(secondsToWaitOnShutdown, TimeUnit.SECONDS)) {
                    logger.warn(
                            "Timeout during shutdown of async job executor. The current running jobs could not end within {} seconds after shutdown operation.",
                            secondsToWaitOnShutdown);
                }
            } catch (InterruptedException e) {
                logger.warn("Interrupted while shutting down the async job executor. ", e);
                Thread.currentThread().interrupt();
            }

            executorService = null;
        }
    }

    protected ExecutorService initializeExecutor() {
        if (threadPoolQueue == null) {
            int queueSize = getQueueSize();
            logger.info("Creating thread pool queue of size {}", queueSize);
            threadPoolQueue = new ArrayBlockingQueue<>(queueSize);
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Increase the await-termination period so running jobs can finish, e.g. flowable.async.executor.await-termination-period=60s (Spring) or configuration.setAwaitTerminationPeriod(Duration.ofSeconds(60))
  2. Reduce job duration/size: break long work into smaller async steps or set timeouts on external calls inside the job
  3. Check for stuck/hung jobs (e.g. blocked HTTP clients) and add timeouts or circuit breakers so workers free up at shutdown
  4. If graceful drain is not needed, treat this warning as expected; the engine will retry unfinished jobs on next startup
  5. Ensure jobs are actually processed during shutdown by stopping job acquisition first (flowable.async.executor.async-job-acquisition-enabled=false via actuator/pre-shutdown hook) if appropriate

Example fix

// before
engineConfig.getAsyncExecutor().setAwaitTerminationPeriod(Duration.ofSeconds(2));
// after
engineConfig.getAsyncExecutor().setAwaitTerminationPeriod(Duration.ofSeconds(120));
Defensive patterns

Strategy: validation

Validate before calling

// Before shutdown, check for jobs still in flight and size the termination window accordingly
long active = managementService.createJobQuery().count();
Duration wait = engineConfig.getAsyncExecutor().getAwaitTerminationPeriod();
if (active > 0 && wait.toSeconds() < expectedMaxJobSeconds) {
  throw new IllegalStateException(active + " jobs running; await-termination-period " + wait + "s is too short");
}

Try / catch

// No exception thrown; detect via elapsed shutdown time / job state after restart
try {
  engine.close();
} catch (RuntimeException e) {
  logger.warn("Async executor may have discarded running jobs; verify job retries on next startup", e);
}

Prevention

When it happens

Trigger: Calling shutdown (during engine close or application shutdown) while long-running async jobs are still executing and the configured awaitTerminationPeriod (flowable.async.executor.await-termination-period / defaultAsyncTaskExecutor) is shorter than the jobs' remaining runtime.

Common situations: Spring Boot app shut down or redeployed while long async jobs (timers, big service tasks, HTTP calls) run; await-termination period left at a small default; a job hung on a slow external service blocking the worker thread.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/ece14dcaf4e5bf3f. Report an issue: GitHub.