quarkusio/quarkus · warning · RuntimeException
java.util.concurrent.ExecutionException wrapped SchedulerExc
Error message
java.util.concurrent.ExecutionException wrapped SchedulerException from scheduler.shutdown(true)
What it means
During graceful shutdown with a non-zero quarkus.quartz.shutdown-wait-time, Quarkus calls scheduler.shutdown(true) in a CompletableFuture and wraps any SchedulerException from it in a RuntimeException inside the async supplier. The outer future then fails with a TimeoutException on expiry or an ExecutionException wrapping this RuntimeException. This exception is caught by destroy() and only logged as a warning — the application still shuts down.
Source
Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:550
* Need to gracefully shut down the scheduler making sure that all triggers have been
* released before datasource shutdown.
*
* @param event ignored
*/
void destroy(@Observes(notifyObserver = Reception.IF_EXISTS) @BeforeDestroyed(ApplicationScoped.class) Object event) {
if (scheduler != null) {
try {
if (shutdownWaitTime.isZero()) {
scheduler.shutdown(false);
} else {
CompletableFuture.supplyAsync(new Supplier<>() {
@Override
public Void get() {
// Note that this method does not return until all currently executing jobs have completed
try {
scheduler.shutdown(true);
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
return null;
}
}).get(shutdownWaitTime.toMillis(), TimeUnit.MILLISECONDS);
}
} catch (Exception e) {
LOGGER.warnf("Unable to gracefully shutdown the scheduler", e);
}
}
}
@PreDestroy
void destroy() {
if (scheduler != null) {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown(false); // force shutdownView on GitHub (pinned to e1c734241f)
Solutions
- Increase quarkus.quartz.shutdown-wait-time to exceed the longest job duration
- Make jobs interruptible/cooperative so shutdown(true) completes quickly
- Ensure the datasource remains available until scheduler shutdown completes (Quarkus handles ordering, but verify custom ordering)
- Treat this log warning as non-fatal; set shutdown-wait-time to 0 (PT0S) to skip graceful wait and force shutdown
Example fix
// before (application.properties) quarkus.quartz.shutdown-wait-time=5S // after quarkus.quartz.shutdown-wait-time=60S # longer than the slowest job
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure jobs finish before shutdown-wait-time expires Duration longestJob = measureLongestJob(); assert shutdownWaitTime.compareTo(longestJob) > 0;
Try / catch
// Quarkus logs this as a warning in destroy(); no user catch needed.
// For custom shutdown code:
try {
future.get(waitMillis, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
LOGGER.warn("Graceful quartz shutdown timed out; jobs may still be running");
} catch (ExecutionException e) {
LOGGER.warnf(e.getCause(), "Quartz graceful shutdown failed");
} Prevention
- Set quarkus.quartz.shutdown-wait-time above your longest job duration
- Keep jobs interruptible so shutdown(true) returns promptly
- Treat the log warning as informational — shutdown proceeds anyway
- Use store-type=memory to avoid store failures during shutdown
When it happens
Trigger: Application shutdown with shutdown-wait-time > 0 while scheduler.shutdown(true) (wait for running jobs to complete) throws SchedulerException — e.g. JobStore error while waiting on JDBC store, or the shutdown interrupted by store failure.
Common situations: Long-running jobs exceeding shutdown-wait-time (TimeoutException path); JDBC store failing during shutdown; DB already torn down before the scheduler's graceful shutdown runs.
Related errors
- Quartz scheduler is either explicitly disabled through quark
- Unable to pause scheduler
- Unable to pause job
- Unable to resume scheduler
- Unable to resume job
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e35e24f143597110.
Report an issue: GitHub.