flowable/flowable-engine · error · FlowableException
failedJobRetryTimeCycle has wrong format:" +…
Error message
failedJobRetryTimeCycle has wrong format:" + failedJobRetryTimeCycleValue + " for execution " + executionEntity
What it means
JobRetryCmd parses the failedJobRetryTimeCycle value (e.g. 'R5/PT1M') to compute job retry decrements. If parsing/applying the retry cycle throws any Exception, it is wrapped as FlowableException 'failedJobRetryTimeCycle has wrong format:<value> for execution <execution>', with the original parse failure as cause.
Solutions
- Fix the failedJobRetryTimeCycle value to valid ISO-8601 repetition format, e.g. 'R3/PT10M' (3 retries every 10 minutes).
- Check the exception cause in the logs to see exactly which parser rejected the value.
- If the value comes from a placeholder/property, confirm it resolves to a literal value before deployment.
- Remove the cycle temporarily to let the job fail normally while you correct configuration.
Example fix
// before
<flowable:failedJobRetryTimeCycle>${retryCycle}</flowable:failedJobRetryTimeCycle>
// after
<flowable:failedJobRetryTimeCycle>R5/PT7M</flowable:failedJobRetryTimeCycle> Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern RETRY_CYCLE =
Pattern.compile("^R\\d+/PT?\\d+[HMS]$");
if (!RETRY_CYCLE.matcher(failedJobRetryTimeCycle).matches()) {
throw new IllegalArgumentException("Invalid retry time cycle: " + failedJobRetryTimeCycle);
} Type guard
boolean isValidRetryTimeCycle(String v) {
return v != null && v.matches("^R\\d+/PT?\\d+[HMS]$");
} Try / catch
try {
managementService.moveJobToDeadLetterJob(jobId);
} catch (FlowableException e) {
if (e.getMessage().contains("failedJobRetryTimeCycle has wrong format")) {
log.error("Fix failedJobRetryTimeCycle value; cause: {}", e.getCause(), e);
}
throw e;
} Prevention
- Use ISO-8601 repetition format like R5/PT10M for failedJobRetryTimeCycle
- Verify placeholders in BPMN XML resolve to literals before deployment
- Validate the cycle string in a unit test parsing it with the same engine parser
When it happens
Trigger: An async job failed and the execution/element has a failedJobRetryTimeCycle configured (in BPMN extension elements or process engine configuration) whose value is not a valid ISO-8601 repetition interval, e.g. '5', 'R/PT10M', 'PTx', or containing typos.
Common situations: Typo in the time cycle string in the BPMN XML; property placeholder not resolved so a raw '${retryCycle}' ends up in the value; copying examples with wrong interval syntax; configuration injected from environment variables with bad values.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Could not deserialize job configuration
- Invalid usage of job handler, case instance was not found.
- Invalid usage of job handler, variable scope is of type
- jobId is null
- jobId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f7ba38be8af13d6a.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/JobRetryCmd.java:144
if (jobRetries <= 1 || isUnrecoverableException()) {
newJobEntity = jobService.moveJobToDeadLetterJob(job);
} else {
newJobEntity = timerJobService.moveJobToTimerJob(job);
}
newJobEntity.setDuedate(durationHelper.getDateAfter());
if (job.getExceptionMessage() == null) { // is it the first exception
LOGGER.debug("Applying JobRetryStrategy '{}' the first time for job {} with {} retries", failedJobRetryTimeCycleValue, job.getId(), durationHelper.getTimes());
} else {
LOGGER.debug("Decrementing retries of JobRetryStrategy '{}' for job {}", failedJobRetryTimeCycleValue, job.getId());
}
newJobEntity.setRetries(jobRetries - 1);
} catch (Exception e) {
throw new FlowableException("failedJobRetryTimeCycle has wrong format:" + failedJobRetryTimeCycleValue + " for execution " + executionEntity, e);
}
}
if (exception != null) {
newJobEntity.setExceptionMessage(exception.getMessage());
newJobEntity.setExceptionStacktrace(getExceptionStacktrace());
}
// Dispatch both an update and a retry-decrement event
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, newJobEntity),
processEngineConfiguration.getEngineCfgKey());
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_RETRIES_DECREMENTED, newJobEntity),
processEngineConfiguration.getEngineCfgKey());
}
View on GitHub (pinned to d6d39ce1c6)