{"record":{"id":"066201d7b38294de","repo":"quarkusio/quarkus","slug":"a-job-with-this-identity-is-already-scheduled-id","errorCode":null,"errorMessage":"A job with this identity is already scheduled: {identity}","messagePattern":"A job with this identity is already scheduled: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java","lineNumber":1051,"sourceCode":"                vertx, task != null && runtimeConfig.runBlockingScheduledMethodOnQuartzThread(),\n                SchedulerUtils.parseExecutionMaxDelayAsMillis(scheduled), blockingExecutor);\n        QuartzTrigger quartzTrigger = new QuartzTrigger(trigger.getKey(),\n                new Function<>() {\n                    @Override\n                    public org.quartz.Trigger apply(TriggerKey triggerKey) {\n                        try {\n                            return scheduler.getTrigger(triggerKey);\n                        } catch (SchedulerException e) {\n                            throw new IllegalStateException(e);\n                        }\n                    }\n                }, invoker,\n                SchedulerUtils.parseOverdueGracePeriod(scheduled, defaultOverdueGracePeriod),\n                runtimeConfig.runBlockingScheduledMethodOnQuartzThread(), true, null, description);\n        QuartzTrigger existing = scheduledTasks.putIfAbsent(scheduled.identity(), quartzTrigger);\n\n        if (existing != null) {\n            throw new IllegalStateException(\"A job with this identity is already scheduled: \" + scheduled.identity());\n        }\n\n        try {\n            if (oldTrigger != null) {\n                scheduler.rescheduleJob(trigger.getKey(), trigger);\n                LOGGER.debugf(\"Rescheduled job definition with config %s\", scheduled);\n            } else {\n                scheduler.scheduleJob(jobDetail, trigger);\n                LOGGER.debugf(\"Scheduled job definition with config %s\", scheduled);\n            }\n        } catch (SchedulerException e) {\n            throw new IllegalStateException(e);\n        }\n        return quartzTrigger;\n    }\n\n    /**\n     * @see Nonconcurrent","sourceCodeStart":1033,"sourceCodeEnd":1069,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java#L1033-L1069","documentation":"Quarkus Scheduler allows only one task per identity. When scheduling programmatically, `scheduledTasks.putIfAbsent` reveals that an identity is already registered, so an IllegalStateException naming the identity is thrown to prevent duplicate jobs.","triggerScenarios":"Calling `scheduler.newJob(\"sameId\")...schedule()` twice, or scheduling programmatically an identity already defined by a @Scheduled annotation on a bean.","commonSituations":"Application restart code paths re-registering jobs idempotently; duplicate @Scheduled identity values across beans; test code scheduling the same identity repeatedly within one application instance.","solutions":["Use a unique identity per schedule, or check `scheduler.getScheduledJobs()`/unwrap existing QuartzTrigger before scheduling","Make scheduling idempotent: skip when the identity already exists instead of calling schedule again","Rename one of the conflicting @Scheduled identities (annotation and programmatic identity must not collide)"],"exampleFix":"// before\nscheduler.newJob(\"sync\").setEvery(\"10m\").setTask(t -> sync()).schedule(); // second call throws\n// after\nif (scheduler.getJobByIdentity(\"sync\").isEmpty()) {\n    scheduler.newJob(\"sync\").setEvery(\"10m\").setTask(t -> sync()).schedule();\n}","handlingStrategy":"try-catch","validationCode":"boolean taken = scheduler.getScheduledJobs().stream()\n    .anyMatch(j -> j.getSchedule().identity().equals(\"myJob\"));\nif (taken) { /* skip or unschedule first */ }","typeGuard":null,"tryCatchPattern":"try {\n    scheduler.newJob(\"myJob\").setEvery(\"10m\").setTask(t -> run()).schedule();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"already scheduled\")) { /* skip duplicate registration */ }\n}","preventionTips":["Generate unique identities or reuse a constant per logical job","Make re-registration idempotent with an identity check","Avoid programmatic identities that shadow @Scheduled annotation identities"],"tags":["quarkus","quartz","duplicate-identity","programming-error"],"backgroundTag":"job-already-scheduled-conflict","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}