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

  1. Check existence first: skip creation when the identity is already scheduled, or unscheduleJob(identity) before newJob(identity).
  2. Generate unique identities (e.g. append a UUID or timestamp) when jobs are created dynamically.
  3. Initialize job registration in exactly one place (a single StartupEvent observer or Scheduler schedulerNewJob flow) to avoid duplicate registration.
  4. Catch IllegalStateException and treat it as 'already registered' if duplicate creation is expected.
  5. 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

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


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