quarkusio/quarkus · error · IllegalStateException
Job [{identity}] that was previously scheduled programmatica
Error message
Job [{identity}] that was previously scheduled programmatically cannot be disabled What it means
When a scheduled application's job is disabled (@Scheduled{enabled=false} or equivalent) but a trigger for the same identity already exists in the Quartz store from a previous programmatic schedule, the scheduler cannot reconcile: it refuses to silently disable a job previously scheduled programmatically and throws IllegalStateException.
Source
Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:1021
jobBuilder.usingJobData(EXECUTION_METADATA_SKIP_PREDICATE_CLASS,
executionMetadata.skipPredicateClass().getName());
}
}
JobDetail jobDetail = jobBuilder.requestRecovery().build();
org.quartz.Trigger trigger;
Optional<TriggerBuilder<?>> triggerBuilder = createTrigger(scheduled.identity(), scheduled, runtimeConfig,
jobDetail, description);
if (triggerBuilder.isPresent()) {
if (oldTrigger != null) {
trigger = triggerBuilder.get().startAt(oldTrigger.getNextFireTime()).build();
} else {
trigger = triggerBuilder.get().build();
}
} else {
if (oldTrigger != null) {
throw new IllegalStateException(
"Job [" + scheduled.identity() + "] that was previously scheduled programmatically cannot be disabled");
}
// Job is disabled
return null;
}
JobInstrumenter instrumenter = null;
if (schedulerConfig.tracingEnabled() && jobInstrumenter.isResolvable()) {
instrumenter = jobInstrumenter.get();
}
invoker = initInvoker(invoker, events, scheduled.concurrentExecution(), skipPredicate, instrumenter,
vertx, task != null && runtimeConfig.runBlockingScheduledMethodOnQuartzThread(),
SchedulerUtils.parseExecutionMaxDelayAsMillis(scheduled), blockingExecutor);
QuartzTrigger quartzTrigger = new QuartzTrigger(trigger.getKey(),
new Function<>() {
@Override
public org.quartz.Trigger apply(TriggerKey triggerKey) {
try {View on GitHub (pinned to e1c734241f)
Solutions
- Delete the stale trigger/job from the Quartz store (scheduler.deleteJob) or clean the QRTZ_ tables for that identity before disabling
- Re-enable the job and remove it programmatically (unschedule) instead of using the disabled flag
- Rename the job identity so the disabled definition no longer collides with the stored trigger
Example fix
// before: disabled job with stale trigger
@Scheduled(identity="reports", disabled=true) ...
// after: unschedule programmatically instead
scheduler.unscheduleJob("reports"); Defensive patterns
Strategy: try-catch
Validate before calling
// check for an existing stored trigger before relying on disabled config org.quartz.Trigger existing = scheduler.getTrigger(new TriggerKey(identity, Scheduler.class.getName())); boolean safeToDisable = existing == null;
Try / catch
try {
schedulerInstance.schedule(...);
} catch (IllegalStateException e) {
if (e.getMessage().contains("cannot be disabled")) { scheduler.deleteJob(jobKey); }
} Prevention
- Unschedule jobs programmatically instead of toggling enabled=false when the store persists triggers
- Clean stale QRTZ_ rows when renaming/removing jobs
- Keep identity values stable between deploys
When it happens
Trigger: Disabling a job (e.g. `quarkus.scheduler.enabled=false` per-job config or property-driven enabled=false) while the DB/job-store still holds a trigger with that identity created earlier by programmatic scheduling.
Common situations: Toggling a job off via config between deploys with a JDBC store; a job previously registered at runtime then disabled in code; stale triggers left in the DB after refactoring.
Related errors
- A skip predicate instance cannot be scheduled programmatical
- A task instance cannot be scheduled programmatically if DB s
- An async task instance cannot be scheduled programmatically
- SchedulerException while getting trigger (no message)
- Clustered jobs configured with unsupported job store option
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5af952c2740930f6.
Report an issue: GitHub.