{"record":{"id":"caeb72e87d30307b","repo":"quarkusio/quarkus","slug":"unable-to-obtain-the-trigger-for-triggerkey","errorCode":null,"errorMessage":"Unable to obtain the trigger for ${triggerKey}","messagePattern":"Unable to obtain the trigger for (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java","lineNumber":297,"sourceCode":"                }\n\n                // Find persistent jobs scheduled with JobDefinition\n                if (storeType.isDbStore()) {\n                    Set<TriggerKey> triggers = scheduler\n                            .getTriggerKeys(GroupMatcher.triggerGroupEquals(Scheduler.class.getName()));\n\n                    for (TriggerKey triggerKey : triggers) {\n                        JobDetail jobDetail = scheduler.getJobDetail(new JobKey(triggerKey.getName(), triggerKey.getGroup()));\n                        if (jobDetail == null) {\n                            throw new IllegalStateException(\"Unable to obtain the job detail for \" + triggerKey);\n                        }\n\n                        String scheduledJson = jobDetail.getJobDataMap().getString(SCHEDULED_METADATA);\n                        if (scheduledJson != null) {\n                            SyntheticScheduled scheduled = SyntheticScheduled.fromJson(scheduledJson);\n                            org.quartz.Trigger oldTrigger = scheduler.getTrigger(triggerKey);\n                            if (oldTrigger == null) {\n                                throw new IllegalStateException(\"Unable to obtain the trigger for \" + triggerKey);\n                            }\n                            createJobDefinitionQuartzTrigger(new SerializedExecutionMetadata(jobDetail), scheduled, oldTrigger);\n                        }\n                    }\n                }\n\n                if (transaction != null) {\n                    transaction.commit();\n                }\n            } catch (Throwable e) {\n                if (transaction != null) {\n                    try {\n                        transaction.rollback();\n                    } catch (SystemException ex) {\n                        LOGGER.error(\"Unable to rollback transaction\", ex);\n                    }\n                }\n                throw new IllegalStateException(\"Unable to create Scheduler\", e);","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java#L279-L315","documentation":"Immediately after resolving the JobDetail, the same re-scheduling loop fetches the actual org.quartz.Trigger for each stored trigger key. If the trigger itself cannot be retrieved (null), IllegalStateException 'Unable to obtain the trigger for <triggerKey>' is thrown, indicating the trigger disappeared or is unreadable between listing and fetching.","triggerScenarios":"A trigger listed by getTriggerKeys returns null from scheduler.getTrigger(triggerKey) — concurrent deletion by another scheduler instance on a shared store, corrupted trigger row, or unsupported/corrupt trigger type in the store.","commonSituations":"Concurrent schedulers on a shared JDBC store racing with startup re-scheduling; manual deletion of QRTZ_TRIGGERS rows; deserialization failures of stored trigger data.","solutions":["Ensure only one scheduler group/name is active on the shared store; set unique quarkus.quartz.scheduler-name per logical app or stop competing instances.","Clean inconsistent Quartz tables and restart so triggers are recreated.","Check Quartz table serialization data (JOB_DATA blobs) for corruption and remove broken rows.","Verify no external cleanup job deletes triggers during application startup."],"exampleFix":"// before: two apps sharing scheduler name on one DB\nquarkus.quartz.scheduler-name=quarkusQuartzScheduler // in both apps\n\n// after: isolate or coordinate\napp1: quarkus.quartz.scheduler-name=app1Scheduler\napp2: quarkus.quartz.scheduler-name=app2Scheduler","handlingStrategy":"retry","validationCode":"// re-fetch with a short delay to rule out concurrent-store races\nTriggerKey key = /* ... */;\norg.quartz.Trigger t = scheduler.getTrigger(key);\nif (t == null) {\n    Thread.sleep(1000);\n    t = scheduler.getTrigger(key);\n}\nif (t == null) throw new IllegalStateException(\"Trigger missing from store: \" + key);","typeGuard":null,"tryCatchPattern":"try {\n    scheduler.start();\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Unable to obtain the trigger\")) {\n        // verify no other instance deletes triggers concurrently; purge inconsistent rows\n        throw new RuntimeException(\"Quartz store trigger missing — check competing schedulers\", e);\n    }\n    throw e;\n}","preventionTips":["Isolate scheduler names across apps sharing one JDBC store.","Disable external cleanup scripts that run during app startup windows.","Monitor QRTZ_TRIGGERS/QRTZ_JOB_DETAILS consistency in DB health checks."],"tags":["quarkus","quartz","jdbc-store","race-condition","startup"],"backgroundTag":"quartz-store-inconsistent-state","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"}