flowable/flowable-engine · error · ParseException
Illegal characters for this position: '
Error message
Illegal characters for this position: '
What it means
The final fallback in storeExpressionVals: the current field's first token does not match any known type handler (second-of-minute, minute, hour, day-of-month, month, day-of-week) keyword/value forms, so the parser rejects the token as illegal for that position. This typically means the cron string has the wrong number of fields or contains characters the field grammar does not allow.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java:603
}
} else if (c == '#') {
try {
i += 4;
nthdayOfWeek = Integer.parseInt(s.substring(i));
if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
throw new Exception();
}
} catch (Exception e) {
throw new ParseException("A numeric value between 1 and 5 must follow the '#' option", i);
}
} else if (c == 'L') {
lastdayOfWeek = true;
i++;
}
}
} else {
throw new ParseException("Illegal characters for this position: '" + sub + "'", i);
}
if (eval != -1) {
incr = 1;
}
addToSet(sval, eval, incr, type);
return (i + 3);
}
if (c == '?') {
i++;
if ((i + 1) < s.length() && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) {
throw new ParseException("Illegal character after '?': " + s.charAt(i), i);
}
if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {
throw new ParseException("'?' can only be specified for Day-of-Month or Day-of-Week.", i);
}
if (type == DAY_OF_WEEK && !lastdayOfMonth) {
int val = daysOfMonth.last();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Expand shorthand macros manually: '@daily' -> '0 0 0 * * ?'.
- Count the fields: Quartz-style cron needs 6 or 7 (sec min hour dom month dow [year]).
- Check each field's legal characters; alphabetic names only for month (JAN-DEC) and day-of-week (SUN-SAT).
- Log/inspect the actual expression string at parse time — a template or property substitution may be injecting bad text.
Example fix
// before
new CronExpression("@daily");
// after
new CronExpression("0 0 0 * * ?"); Defensive patterns
Strategy: validation
Validate before calling
int fields = expr.trim().split("\\s+").length;
if (fields < 6 || fields > 7) {
throw new IllegalArgumentException("Cron must have 6-7 fields: " + expr);
}
if (expr.startsWith("@")) {
throw new IllegalArgumentException("Shorthand macros (@daily) not supported; expand manually");
} Try / catch
try {
new CronExpression(expr);
} catch (java.text.ParseException e) {
throw new IllegalArgumentException("Unparseable cron expression: " + expr, e);
} Prevention
- Never use Unix @macros; expand to 6-field form
- Verify field count before parsing
- Inspect raw config values — templating may inject garbage tokens
When it happens
Trigger: new CronExpression("0 0 12 * * * FOO") or any expression where a field starts with characters that fit no pattern — e.g. 8 tokens where the 8th lands where no handler exists, or an alphabetic token in a purely numeric field like month 'JANU' typo, or using '@daily' shorthand macros which Quartz-style parsers do not support.
Common situations: Using Unix shorthand macros ('@hourly', '@reboot') not supported by Flowable/Quartz cron; wrong field count causing tokens to fall in unexpected positions; stray whitespace-split garbage from config files; environment-variable substitution leaving 'unset' or empty-derived junk in the expression.
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
- Illegal character after ?:
- Invalid Day-of-Week value: '
- A numeric value between 1 and 5 must follow the '#' option
- '?' can only be specified for Day-of-Month or Day-of-Week.
- '?' can only be specified for Day-of-Month -OR- Day-of-Week.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a0c50af0aa2dd4ef.
Report an issue: GitHub.