quarkusio/quarkus · error · IllegalStateException

SchedulerException while scheduling job (no message)

Error message

SchedulerException while scheduling job (no message)

What it means

When a scheduled job definition is registered programmatically, QuartzSchedulerImpl calls scheduler.scheduleJob(jobDetail, trigger) (or reschedules). If the underlying Quartz Scheduler throws a SchedulerException — e.g. the scheduler is not started/shut down, the JobDetail/Trigger pair is invalid, or the job store rejected the operation — it is wrapped in an IllegalStateException and rethrown to the caller of the public scheduling API.

Source

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

                }, invoker,
                SchedulerUtils.parseOverdueGracePeriod(scheduled, defaultOverdueGracePeriod),
                runtimeConfig.runBlockingScheduledMethodOnQuartzThread(), true, null, description);
        QuartzTrigger existing = scheduledTasks.putIfAbsent(scheduled.identity(), quartzTrigger);

        if (existing != null) {
            throw new IllegalStateException("A job with this identity is already scheduled: " + scheduled.identity());
        }

        try {
            if (oldTrigger != null) {
                scheduler.rescheduleJob(trigger.getKey(), trigger);
                LOGGER.debugf("Rescheduled job definition with config %s", scheduled);
            } else {
                scheduler.scheduleJob(jobDetail, trigger);
                LOGGER.debugf("Scheduled job definition with config %s", scheduled);
            }
        } catch (SchedulerException e) {
            throw new IllegalStateException(e);
        }
        return quartzTrigger;
    }

    /**
     * @see Nonconcurrent
     */
    @DisallowConcurrentExecution
    static class NonconcurrentInvokerJob extends InvokerJob {

        NonconcurrentInvokerJob(QuartzTrigger trigger, Vertx vertx) {
            super(trigger, vertx);
        }

        @Override
        boolean awaitResult() {
            return true;
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check the wrapped SchedulerException's message/cause (IllegalStateException.getCause()) for the real Quartz failure reason
  2. Verify the job store configuration (quarkus.quartz.store-type); for jdbc-store confirm the datasource is configured and reachable at startup
  3. Ensure you do not schedule jobs manually while the Quarkus scheduler is shut down or still starting
  4. If rescheduling, make sure the job identity and trigger definition match what is stored, or delete the job first
  5. Fix any earlier startup failure that caused the scheduler to stop before this job was registered

Example fix

// before
scheduler.scheduleJob(jobDetail, trigger); // throws IllegalStateException wrapping SchedulerException
// after
try {
    scheduler.scheduleJob(jobDetail, trigger);
} catch (IllegalStateException e) {
    LOG.errorf(e.getCause(), "Failed to schedule job %s", jobDetail.getKey());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before scheduling, verify the scheduler is not shutdown and the job key is free
Scheduler s = ...; // obtained from the running Quartz scheduler
if (s.isShutdown()) { throw new IllegalStateException("Scheduler already stopped"); }
if (s.checkExists(jobKey)) { s.deleteJob(jobKey); }

Try / catch

try {
    scheduler.scheduleJob(jobDetail, trigger);
} catch (IllegalStateException e) {
    // cause is the SchedulerException
    Throwable cause = e.getCause();
    LOG.errorf(cause, "Quartz rejected scheduling of %s", jobDetail.getKey());
}

Prevention

When it happens

Trigger: Calling QuartzSchedulerImpl.scheduleJob (or rescheduling an existing job definition) when the Quartz scheduler rejects the JobDetail/Trigger: scheduler already shut down, duplicate job key with incompatible trigger, or a persistent job store (JDBC) failing to persist the job.

Common situations: Registering jobs during startup after the scheduler stopped due to another startup failure; JDBC job store whose datasource is down or misconfigured; scheduling two jobs with the same identity but conflicting settings; live-reload reconfiguration racing a scheduler shutdown.

Related errors


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