quarkusio/quarkus · error · IllegalStateException

An async task instance cannot be scheduled programmatically

Error message

An async task instance cannot be scheduled programmatically if DB store type is used; register an async task class instead

What it means

For async tasks the DB store demands a Function class, not an instance: `setAsyncTask(Function)` throws IllegalStateException when a lambda/instance is supplied while `store-type=db` and `setAsyncTaskClass` was not called.

Source

Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:896

                throw new IllegalStateException(
                        "A skip predicate instance cannot be scheduled programmatically if DB store type is used; register a skip predicate class instead");
            }
            return super.setSkipPredicate(skipPredicate);
        }

        @Override
        public QuartzJobDefinition setTask(Consumer<ScheduledExecution> task, boolean runOnVirtualThread) {
            if (storeType.isDbStore() && taskClass == null) {
                throw new IllegalStateException(
                        "A task instance cannot be scheduled programmatically if DB store type is used; register a task class instead");
            }
            return super.setTask(task, runOnVirtualThread);
        }

        @Override
        public QuartzJobDefinition setAsyncTask(Function<ScheduledExecution, Uni<Void>> asyncTask) {
            if (storeType.isDbStore() && asyncTaskClass == null) {
                throw new IllegalStateException(
                        "An async task instance cannot be scheduled programmatically if DB store type is used; register an async task class instead");
            }
            return super.setAsyncTask(asyncTask);
        }

        @Override
        public Trigger schedule() {
            checkScheduled();
            if (task == null && asyncTask == null) {
                throw new IllegalStateException("Either sync or async task must be set");
            }
            scheduled = true;
            SyntheticScheduled scheduled = new SyntheticScheduled(identity, cron, every, 0, TimeUnit.MINUTES, delayed,
                    overdueGracePeriod, concurrentExecution, skipPredicate, timeZone, implementation, executionMaxDelay,
                    description);
            return createJobDefinitionQuartzTrigger(this, scheduled, null);
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Create a class implementing `Function<ScheduledExecution, Uni<Void>>` and register it with `setAsyncTaskClass(MyAsyncTask.class)`
  2. Change store type to memory when persistence is not required
  3. Review all programmatic jobs after switching store-type to db and convert lambdas to classes

Example fix

// before
job.setAsyncTask(ctx -> refreshCache());
// after
job.setAsyncTaskClass(RefreshCacheTask.class); // implements Function<ScheduledExecution, Uni<Void>>
Defensive patterns

Strategy: validation

Validate before calling

if (quarkusQuartzConfig.storeType().isDbStore()) {
    job.setAsyncTaskClass(MyAsyncTask.class);
} else {
    job.setAsyncTask(ctx -> runAsync(ctx));
}

Prevention

When it happens

Trigger: Calling `quartzJobDefinition.setAsyncTask(exec -> Uni.createFrom().voidItem())` with DB store and no async task class registered.

Common situations: Reactive scheduled jobs written with lambdas that worked with in-memory store; JDBC store enabled via config change, breaking existing programmatic schedules at startup.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7b8d9604d289049b. Report an issue: GitHub.