xuxueli/xxl-job · error · ParseException
Month values must be between 1 and 12
Error message
Month values must be between 1 and 12
What it means
Thrown by CronExpression's field-validation routine (addToSet) when the MONTH token holds a value below 1 or above 12, or a range whose upper bound exceeds 12. Months are 1-based (1=Jan ... 12=Dec). Only the '*' wildcard (ALL_SPEC_INT=99) is exempt; '?' is not valid for the month field.
Source
Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:1005
if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {
throw new ParseException(
"Minute and Second values must be between 0 and 59",
-1);
}
} else if (type == HOUR) {
if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {
throw new ParseException(
"Hour values must be between 0 and 23", -1);
}
} else if (type == DAY_OF_MONTH) {
if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)
&& (val != NO_SPEC_INT)) {
throw new ParseException(
"Day of month values must be between 1 and 31", -1);
}
} else if (type == MONTH) {
if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {
throw new ParseException(
"Month values must be between 1 and 12", -1);
}
} else if (type == DAY_OF_WEEK) {
if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)
&& (val != NO_SPEC_INT)) {
throw new ParseException(
"Day-of-Week values must be between 1 and 7", -1);
}
}
if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) {
if (val != -1) {
set.add(val);
} else {
set.add(NO_SPEC);
}
return;View on GitHub (pinned to e74c784f68)
Solutions
- Keep month literals in 1-12 (January=1, December=12).
- Use '*' for every month; do not use '?' here (month has no NO_SPEC exemption).
- Add a parsing test for generated cron strings before persisting.
Example fix
// before
new CronExpression("0 0 12 * 13 ?"); // month 13 invalid
// after
new CronExpression("0 0 12 * 12 ?"); // December = 12 Defensive patterns
Strategy: validation
Validate before calling
// Guard month literals 1-12 before parsing
String[] f = expr.trim().split("\\s+");
String mon = (f.length >= 6) ? f[4] : f[3];
if (mon.matches("\\d+")) {
int m = Integer.parseInt(mon);
if (m < 1 || m > 12) throw new IllegalArgumentException("month out of range: " + m);
} Try / catch
try {
CronExpression c = new CronExpression(expr);
} catch (java.text.ParseException e) {
log.warn("Invalid cron '{}': {}", expr, e.getMessage());
} Prevention
- Months are 1-based (1=Jan ... 12=Dec); '?' is not valid for month.
- Validate generated cron strings with a parse test before saving.
- Do not emit 0 for January.
When it happens
Trigger: Constructing CronExpression with a month like "13", "0", or a range "1-14". Occurs during expression parsing/construction.
Common situations: Using 0 to mean January (it is 1 here); off-by-one from a zero-indexed month list; copy-pasting schedules from systems with different month encoding.
Related errors
- Hour values must be between 0 and 23
- Day of month values must be between 1 and 31
- Start year must be less than stop year
- '?' can only be specified for Day-of-Month -OR- Day-of-Week.
- '/' must be followed by an integer.
AI-assisted analysis of xuxueli/xxl-job@e74c784f68 (2026-08-14).
Data as JSON: /api/errors/27163a239c83acae.
Report an issue: GitHub.