flowable/flowable-engine · error · FlowableObjectNotFoundException

No timer job found with id

Error message

No timer job found with id '${jobId}'.

What it means

SetTimerJobRetriesCmd.execute throws this FlowableObjectNotFoundException when no timer job entity exists in the ACT_RU_TIMER_JOB table for the given id (with type Job.class). The command validated the id format but the lookup returned null, so the retries cannot be updated.

Solutions

  1. Verify the id is a timer job id (query ACT_RU_TIMER_JOB or use TimerJobQuery)
  2. Catch FlowableObjectNotFoundException and treat the job as already executed/removed if that is an acceptable outcome
  3. Check you are connected to the correct datasource/schema and the process is still running
  4. Refresh the job id from a fresh TimerJobQuery before retrying the update

Example fix

// before
managementService.setTimerJobRetries(timerJobId, 3);
// after
TimerJob timerJob = managementService.createTimerJobQuery(). jobId(timerJobId).singleResult();
if (timerJob != null) {
    managementService.setTimerJobRetries(timerJobId, 3);
} else {
    logger.warn("Timer job {} no longer exists; skipping retry update", timerJobId);
}
Defensive patterns

Strategy: try-catch

Validate before calling

TimerJob job = managementService.createTimerJobQuery().jobId(timerJobId).singleResult();
if (job == null) { /* skip or warn */ }

Try / catch

try {
    managementService.setTimerJobRetries(timerJobId, 3);
} catch (FlowableObjectNotFoundException e) {
    logger.warn("Timer job {} not found; already executed or removed", timerJobId);
}

Prevention

When it happens

Trigger: Calling setTimerJobRetries with an id belonging to a regular async job, suspended job, dead-letter job, or history-only (deleted runtime) job; passing an id that was already consumed because the timer fired and the job moved/executed; stale id from a completed process.

Common situations: Confusing timer job ids with job-entity ids from a different table; the timer fired between listing it and updating it; running against a different database/schema than the one the job was created in; process finished and runtime data cleaned up.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/05ad1938c20147be. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/SetTimerJobRetriesCmd.java:65

        this.jobId = jobId;
        this.retries = retries;
        this.jobServiceConfiguration = jobServiceConfiguration;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        TimerJobEntity job = jobServiceConfiguration.getTimerJobEntityManager().findById(jobId);
        if (job != null) {

            job.setRetries(retries);

            FlowableEventDispatcher eventDispatcher = jobServiceConfiguration.getEventDispatcher();
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                eventDispatcher.dispatchEvent(FlowableJobEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, job),
                        jobServiceConfiguration.getEngineName());
            }
        } else {
            throw new FlowableObjectNotFoundException("No timer job found with id '" + jobId + "'.", Job.class);
        }
        return null;
    }
}

View on GitHub (pinned to d6d39ce1c6)