quarkusio/quarkus · error · java.lang.IllegalStateException
A job with this identity is already scheduled:
Error message
A job with this identity is already scheduled:
What it means
SimpleScheduler.newJob() refuses to create a new job definition builder when an identity already exists among scheduled tasks. Identities must be unique within the scheduler, so creating a second job with the same name is rejected eagerly with IllegalStateException rather than silently overwriting the existing schedule.
Source
Thrown at extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/SimpleScheduler.java:186
@Override
public boolean isStarted() {
return scheduledExecutor != null;
}
@Override
public String implementation() {
return Scheduled.SIMPLE;
}
@Override
public SimpleJobDefinition newJob(String identity) {
if (!isStarted()) {
throw notStarted();
}
Objects.requireNonNull(identity);
if (scheduledTasks.containsKey(identity)) {
throw new IllegalStateException("A job with this identity is already scheduled: " + identity);
}
return new SimpleJobDefinition(identity, schedulerConfig);
}
@Override
public Trigger unscheduleJob(String identity) {
if (!isStarted()) {
throw notStarted();
}
Objects.requireNonNull(identity);
if (!identity.isEmpty()) {
String parsedIdentity = SchedulerUtils.lookUpPropertyValue(identity);
ScheduledTask task = scheduledTasks.get(parsedIdentity);
if (task != null && task.isProgrammatic) {
if (scheduledTasks.remove(task.trigger.id) != null) {
return task.trigger;
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Check existence first: skip creation when the identity is already scheduled, or unscheduleJob(identity) before newJob(identity).
- Generate unique identities (e.g. append a UUID or timestamp) when jobs are created dynamically.
- Initialize job registration in exactly one place (a single StartupEvent observer or Scheduler schedulerNewJob flow) to avoid duplicate registration.
- Catch IllegalStateException and treat it as 'already registered' if duplicate creation is expected.
- Wrap job registration in an idempotency guard keyed by identity.
Example fix
// before
scheduler.newJob("daily-report");
// after
if (scheduler.scheduledJobDefinitions().stream().noneMatch(j -> j.identity().equals("daily-report"))) {
scheduler.newJob("daily-report");
} Defensive patterns
Strategy: validation
Validate before calling
if (scheduler.isStarted() && scheduler.scheduledJobDefinitions().stream().noneMatch(j -> j.identity().equals(identity))) {
scheduler.newJob(identity);
} Type guard
boolean isIdentityFree(Scheduler scheduler, String identity) {
return scheduler.scheduledJobDefinitions().stream().noneMatch(j -> j.identity().equals(identity));
} Try / catch
try {
scheduler.newJob(identity);
} catch (IllegalStateException e) {
if (!e.getMessage().contains("already scheduled")) throw e;
// identity already in use — proceed or log
} Prevention
- Always check or derive identity uniqueness before newJob()
- Register jobs in a single idempotent initialization point
- Use unscheduleJob() before re-registering the same identity
When it happens
Trigger: Calling scheduler.newJob("some-identity") when a task with that exact identity is already present in the scheduler's scheduledTasks map. The scheduler must already be started (otherwise a different notStarted error is thrown first).
Common situations: Re-running initialization code that schedules jobs without checking existing identities; hot redeploy or restart logic that re-registers the same job; generating job identities from user input or config where duplicates are possible.
Related errors
- Quartz scheduler is either explicitly disabled through quark
- A job with this identity is already scheduled: ${identity}
- A job with this identity is already scheduled: {identity}
- Unable to instantiate the class:
- Could not expand value %s in property %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d3070ba2a2ba515b.
Report an issue: GitHub.