jeecgboot/JeecgBoot · error · ParseException
Illegal characters for this position: '{sub}'
Error message
Illegal characters for this position: '{sub}' What it means
The final else in storeExpressionVals: an uppercase alphabetic character (A-Z) reached the branch that is neither MONTH nor DAY_OF_WEEK, so there is no valid name lookup for it. Since name tokens (JAN, MON, etc.) are only meaningful in month/weekday fields, an alpha char in SECOND/MINUTE/HOUR/DAY_OF_MONTH triggers 'Illegal characters for this position'.
Source
Thrown at jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:601
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) {View on GitHub (pinned to 96fb33f5ec)
Solutions
- Restrict SECOND, MINUTE, HOUR and DAY_OF_MONTH fields to numeric values, '*', '?', '/' and '-' (and 'L'/'W' only where supported).
- Remove stray letters; if you intended a named value it belongs in MONTH or DAY_OF_WEEK.
- Sanitize user-supplied schedule input by validating field-by-field type before constructing the cron string.
Example fix
// before - alpha in hour field String cron = "0 0 NOON * * ?"; // 'NOO' -> Illegal characters // after - numeric hour (12) String cron = "0 0 12 * * ?";
Defensive patterns
Strategy: validation
Validate before calling
// Fields SECOND, MINUTE, HOUR and DAY_OF_MONTH must be numeric (with operators), not alpha.
public static String validateNumericField(String field, String fieldName) {
if (field == null) return fieldName + " is null";
String t = field.trim().toUpperCase();
if (t.matches("[0-9*/?\\-,LW]+")) return null; // L/W only valid in dom, but let parser refine
if (t.matches(".*[A-Z].*")) return fieldName + " contains illegal alphabetic characters: " + field;
return null;
} Type guard
public static boolean isAlphaFreeNumericField(String field) {
return field != null && !field.toUpperCase().matches(".*[A-Z].*");
} Try / catch
try {
new CronExpression(expr);
} catch (ParseException e) {
if (e.getMessage().startsWith("Illegal characters for this position")) {
return "Only numeric values (and * ? / -) are allowed in second/minute/hour/day-of-month. " + e.getMessage();
}
throw e;
} Prevention
- Reject letters in second/minute/hour/day-of-month fields at the input boundary.
- Restrict those fields to the charset [0-9*?/-] (plus L/W for dom only).
- Use a cron field builder that types each field (numeric vs name) instead of free text.
When it happens
Trigger: Alpha letters placed in a numeric-only field: '0 0 ABC * * ?' (HOUR='ABC'), 'S * * * * ?' (SECOND), 'A B C D E F' garbage, or a stray letter glued to a number like '0 0 1H0 * * ?'. Also a day-of-month token starting with a letter that is not 'L'/'LW' (the L check happens in a later branch but only for the leading char).
Common situations: Confusing Linux crond day names with Quartz syntax; pasting a malformed fragment; building the second/minute/hour fields from user free-text that contains letters.
Related errors
- Illegal cron expression format ({e})
- Invalid Month value: '{sub}'
- Invalid Day-of-Week value: '{sub}'
- A numeric value between 1 and 5 must follow the '#' option
- Illegal character after '?': {s.charAt(i)}
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/594b58fa8bbbce63.
Report an issue: GitHub.