quarkusio/quarkus · error · IllegalStateException

Either sync or async task must be set

Error message

Either sync or async task must be set

What it means

`QuartzJobDefinitionImpl.schedule()` refuses to schedule a definition that has neither a synchronous task (`setTask`) nor an asynchronous task (`setAsyncTask`). The job would have nothing to execute, so an IllegalStateException is thrown before creating the Quartz trigger.

Source

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

                        "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);
        }

    }

    interface ExecutionMetadata {

        Consumer<ScheduledExecution> task();

        Class<? extends Consumer<ScheduledExecution>> taskClass();

        Function<ScheduledExecution, Uni<Void>> asyncTask();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add a task to the definition before schedule(): `.setTask(exec -> ...)` or `.setAsyncTask(exec -> ...)`
  2. If a class was intended, ensure setTaskClass/setAsyncTaskClass is actually resolving into a task, or call the instance variant directly
  3. Assert in dev tests that every programmatic job definition sets a task

Example fix

// before
scheduler.newJob("nightly").setCron("0 0 2 * * ?").schedule();
// after
scheduler.newJob("nightly").setCron("0 0 2 * * ?").setTask(e -> runNightly()).schedule();
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(task, "task");
Objects.requireNonNull(asyncTask, "asyncTask");
if (task == null && asyncTask == null) throw new IllegalStateException("set task before schedule");

Try / catch

try { def.schedule(); } catch (IllegalStateException e) { log.error("Job {} incomplete: {}", identity, e.getMessage()); }

Prevention

When it happens

Trigger: Calling `scheduler.newJob("id").setCron(...)...schedule()` without ever calling setTask/setAsyncTask (only e.g. setSkipPredicate or setTaskClass-related metadata set but no task).

Common situations: Builder-chain refactors dropping the setTask call; conditional code that sets the task on some paths but not others; copying a job definition template without filling in the task.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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