quarkusio/quarkus · error · IllegalStateException

Unable to obtain the job detail for ${triggerKey}

Error message

Unable to obtain the job detail for ${triggerKey}

What it means

On startup with a persistent Quartz store, QuartzSchedulerImpl re-schedules synthetic @Scheduled triggers by looking up each stored trigger's JobDetail via scheduler.getJobDetail(). If the JobDetail is missing (null) while a trigger exists, IllegalStateException 'Unable to obtain the job detail for <triggerKey>' is thrown — the scheduler store is inconsistent.

Source

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

                                            SchedulerUtils.parseOverdueGracePeriod(scheduled, defaultOverdueGracePeriod),
                                            quartzSupport.getRuntimeConfig().runBlockingScheduledMethodOnQuartzThread(), false,
                                            method.getMethodDescription(), description));
                        } else {
                            // The job is disabled
                            scheduler.deleteJob(new JobKey(identity, Scheduler.class.getName()));
                        }
                    }
                }

                // Find persistent jobs scheduled with JobDefinition
                if (storeType.isDbStore()) {
                    Set<TriggerKey> triggers = scheduler
                            .getTriggerKeys(GroupMatcher.triggerGroupEquals(Scheduler.class.getName()));

                    for (TriggerKey triggerKey : triggers) {
                        JobDetail jobDetail = scheduler.getJobDetail(new JobKey(triggerKey.getName(), triggerKey.getGroup()));
                        if (jobDetail == null) {
                            throw new IllegalStateException("Unable to obtain the job detail for " + triggerKey);
                        }

                        String scheduledJson = jobDetail.getJobDataMap().getString(SCHEDULED_METADATA);
                        if (scheduledJson != null) {
                            SyntheticScheduled scheduled = SyntheticScheduled.fromJson(scheduledJson);
                            org.quartz.Trigger oldTrigger = scheduler.getTrigger(triggerKey);
                            if (oldTrigger == null) {
                                throw new IllegalStateException("Unable to obtain the trigger for " + triggerKey);
                            }
                            createJobDefinitionQuartzTrigger(new SerializedExecutionMetadata(jobDetail), scheduled, oldTrigger);
                        }
                    }
                }

                if (transaction != null) {
                    transaction.commit();
                }
            } catch (Throwable e) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Clean the orphaned trigger rows: delete the trigger (or the scheduler group) from the Quartz tables, or wipe Quartz tables and let Quarkus re-schedule.
  2. Ensure all application instances sharing the store use the same quarkus.quartz.scheduler-name and compatible versions.
  3. Restore schema consistency from backup or re-create the store schema.
  4. Check for other clients (scripts, other schedulers) mutating the Quartz tables.

Example fix

-- remove orphaned triggers so Quarkus re-creates them
DELETE FROM QRTZ_TRIGGERS WHERE SCHED_NAME = 'quarkusQuartzScheduler';
DELETE FROM QRTZ_CRON_TRIGGERS WHERE SCHED_NAME = 'quarkusQuartzScheduler';
Defensive patterns

Strategy: validation

Validate before calling

// startup health check on a JDBC store: every trigger must have a job detail
for (TriggerKey key : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(Scheduler.class.getName()))) {
    if (scheduler.getJobDetail(new JobKey(key.getName(), key.getGroup())) == null) {
        log.error("Orphaned trigger in Quartz store: " + key + " — clean QRTZ_TRIGGERS or reset the store");
    }
}

Try / catch

try {
    scheduler.start();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Unable to obtain the job detail")) {
        // inconsistent store: clean Quartz tables and restart
        throw new RuntimeException("Quartz store inconsistent — purge orphaned triggers", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Trigger rows exist in the JDBC (or other persistent) QRTZ_TRIGGERS table but corresponding QRTZ_JOB_DETAILS rows are missing/corrupted — e.g. jobs were removed from another scheduler instance sharing the store, manual DB cleanup, or interrupted schema changes.

Common situations: Multiple apps sharing one Quartz JDBC store with the same scheduler name; manual truncation of QRTZ_JOB_DETAILS; upgrading while old triggers persist; store corruption after crash.

Related errors


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