quarkusio/quarkus · error · IllegalStateException
A task instance cannot be scheduled programmatically if DB s
Error message
A task instance cannot be scheduled programmatically if DB store type is used; register a task class instead
What it means
Same DB-store constraint for tasks: with `store-type=db`, a scheduled job must reference a Task class (reconstructible/serializable), not an inline Consumer instance. `setTask(Consumer, boolean)` throws IllegalStateException when a task instance is given without a task class.
Source
Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:887
@Override
public Class<? extends SkipPredicate> skipPredicateClass() {
return skipPredicateClass;
}
@Override
public QuartzJobDefinition setSkipPredicate(SkipPredicate skipPredicate) {
if (storeType.isDbStore() && skipPredicateClass == null) {
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) {View on GitHub (pinned to e1c734241f)
Solutions
- Define `class MyJob implements Consumer<ScheduledExecution>` and call `setTaskClass(MyJob.class)` instead of passing an instance
- Use `quarkus.quartz.store-type=memory` if DB persistence is unnecessary
- Keep an instance-free path: register the task class as a bean so Quartz can recreate it after restart
Example fix
// before job.setTask(this::sendReport, false); // after job.setTaskClass(SendReportTask.class); // implements Consumer<ScheduledExecution>
Defensive patterns
Strategy: validation
Validate before calling
if (quarkusQuartzConfig.storeType().isDbStore()) {
job.setTaskClass(MyTask.class);
} else {
job.setTask(this::execute, false);
} Prevention
- Always implement tasks as named Consumer<ScheduledExecution> classes
- Keep a startup test that runs with store-type=db
- Avoid lambdas for anything persisted by Quartz
When it happens
Trigger: Calling `quartzJobDefinition.setTask(exec -> doWork(), false)` (or with a non-virtual-thread flag) while `store-type=db` and `setTaskClass` was not invoked.
Common situations: Works in dev/memory store, breaks with JDBC store; passing a method reference or lambda to setTask in production config.
Related errors
- A skip predicate instance cannot be scheduled programmatical
- An async task instance cannot be scheduled programmatically
- Job [{identity}] that was previously scheduled programmatica
- SchedulerException while getting trigger (no message)
- Failed to record call to method ${call.method}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b214ecb193e49d85.
Report an issue: GitHub.