quarkusio/quarkus · error · IllegalStateException

Unable to obtain the trigger for ${triggerKey}

Error message

Unable to obtain the trigger for ${triggerKey}

What it means

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.

Source

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

                }

                // 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) {
                if (transaction != null) {
                    try {
                        transaction.rollback();
                    } catch (SystemException ex) {
                        LOGGER.error("Unable to rollback transaction", ex);
                    }
                }
                throw new IllegalStateException("Unable to create Scheduler", e);

View on GitHub (pinned to e1c734241f)

Solutions

  1. 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.
  2. Clean inconsistent Quartz tables and restart so triggers are recreated.
  3. Check Quartz table serialization data (JOB_DATA blobs) for corruption and remove broken rows.
  4. Verify no external cleanup job deletes triggers during application startup.

Example fix

// before: two apps sharing scheduler name on one DB
quarkus.quartz.scheduler-name=quarkusQuartzScheduler // in both apps

// after: isolate or coordinate
app1: quarkus.quartz.scheduler-name=app1Scheduler
app2: quarkus.quartz.scheduler-name=app2Scheduler
Defensive patterns

Strategy: retry

Validate before calling

// re-fetch with a short delay to rule out concurrent-store races
TriggerKey key = /* ... */;
org.quartz.Trigger t = scheduler.getTrigger(key);
if (t == null) {
    Thread.sleep(1000);
    t = scheduler.getTrigger(key);
}
if (t == null) throw new IllegalStateException("Trigger missing from store: " + key);

Try / catch

try {
    scheduler.start();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Unable to obtain the trigger")) {
        // verify no other instance deletes triggers concurrently; purge inconsistent rows
        throw new RuntimeException("Quartz store trigger missing — check competing schedulers", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Concurrent schedulers on a shared JDBC store racing with startup re-scheduling; manual deletion of QRTZ_TRIGGERS rows; deserialization failures of stored trigger data.

Related errors


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