quarkusio/quarkus · error · IllegalArgumentException
Invalid schedule configuration: {scheduled}
Error message
Invalid schedule configuration: {scheduled} What it means
`createTrigger` builds either a cron or a simple schedule from a SyntheticScheduled descriptor. If the descriptor has neither a cron expression nor an `every` interval, there is no schedule type to build and an IllegalArgumentException is thrown.
Source
Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:796
break;
case SIMPLE_TRIGGER_RESCHEDULE_NEXT_WITH_EXISTING_COUNT:
simpleScheduleBuilder.withMisfireHandlingInstructionNextWithExistingCount();
break;
case SIMPLE_TRIGGER_RESCHEDULE_NEXT_WITH_REMAINING_COUNT:
simpleScheduleBuilder.withMisfireHandlingInstructionNextWithRemainingCount();
break;
case CRON_TRIGGER_DO_NOTHING:
throw new IllegalArgumentException("Simple job " + identity
+ " configured with invalid misfire policy "
+ perJobConfig.misfirePolicy().dashedName() +
"\nValid options are: "
+ QuartzMisfirePolicy.validSimpleValues().stream()
.map(QuartzMisfirePolicy::dashedName)
.collect(Collectors.joining(", ")));
}
scheduleBuilder = simpleScheduleBuilder;
} else {
throw new IllegalArgumentException("Invalid schedule configuration: " + scheduled);
}
TriggerBuilder<?> triggerBuilder = TriggerBuilder.newTrigger()
.withIdentity(identity, Scheduler.class.getName())
.forJob(jobDetail)
.withSchedule(scheduleBuilder);
if (description != null) {
triggerBuilder.withDescription(description);
}
Long millisToAdd = null;
if (scheduled.delay() > 0) {
millisToAdd = scheduled.delayUnit().toMillis(scheduled.delay());
} else if (!scheduled.delayed().isEmpty()) {
millisToAdd = SchedulerUtils.parseDelayedAsMillis(scheduled);
}
if (millisToAdd != null) {
triggerBuilder.startAt(new Date(Instant.now()View on GitHub (pinned to e1c734241f)
Solutions
- Call `.setCron("0 0/5 * * * ?")` or `.setEvery("10m")` on the QuartzJobDefinition before `.schedule()`
- Verify the configuration source (e.g. @Scheduled expression) actually yields a non-empty cron or every value
- Log the SyntheticScheduled identity/cron/every to find which job lacks a schedule
Example fix
// before
scheduler.newJob("reportJob").setTask(exec -> run()).schedule();
// after
scheduler.newJob("reportJob").setCron("0 0 1 * * ?").setTask(exec -> run()).schedule(); Defensive patterns
Strategy: validation
Validate before calling
boolean schedulable = cron != null && !cron.isBlank() || every != null && !every.isBlank();
if (!schedulable) { throw new IllegalArgumentException("Job needs cron or every"); } Try / catch
try { definition.schedule(); } catch (IllegalArgumentException e) { log.error("Schedule missing: {}", e.getMessage()); } Prevention
- Always chain setCron or setEvery before schedule()
- Centralize job creation in one factory that enforces schedule presence
- Cover each programmatic job with a startup smoke test
When it happens
Trigger: Scheduling a Quartz job programmatically via QuartzJobDefinition with a `cron(...)`/`every(...)` neither set (or both null/empty), so the switch falls to the else branch.
Common situations: Calling `scheduler.newJob(...).schedule()` after building a definition with only identity/description; a builder misuse where `setCron` was expected but never called; misconfigured synthetic scheduled metadata.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Either sync or async task must be set
- A job with this identity is already scheduled: {identity}
- Clustered jobs configured with unsupported job store option
- The Agroal extension is missing and it is required when a Qu
- Custom JDBC delegate implementation class '%s' was not found
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0e3a68d77f02ade6.
Report an issue: GitHub.