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
- Verify the id is a timer job id (query ACT_RU_TIMER_JOB or use TimerJobQuery)
- Catch FlowableObjectNotFoundException and treat the job as already executed/removed if that is an acceptable outcome
- Check you are connected to the correct datasource/schema and the process is still running
- 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
- Confirm the id exists via createTimerJobQuery before updating
- Expect timers to disappear once fired; design handlers to tolerate absence
- Point at the correct datasource/schema
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
- Active execution could not be found with activity id
- Batch part with id ' ' does not have a batch part document.
- Batch with id ' ' does not have a batch document.
- Cannot associate execution by id: no execution with id '
- Cannot find activity '" + activityId + "' in process…
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)