xuxueli/xxl-job · error · ParseException
Hour values must be between 0 and 23
Error message
Hour values must be between 0 and 23
What it means
Thrown by CronExpression's field-validation routine (addToSet) when the HOUR token of a cron expression contains a value below 0 or above 23, or a range whose upper bound exceeds 23. The '*' wildcard is stored internally as ALL_SPEC_INT (99) and is exempt, so every literal hour must fall in the inclusive range 0-23.
Source
Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:994
}
return i;
}
protected void addToSet(int val, int end, int incr, int type)
throws ParseException {
TreeSet<Integer> set = getSet(type);
if (type == SECOND || type == MINUTE) {
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);View on GitHub (pinned to e74c784f68)
Solutions
- Replace any hour literal outside 0-23 with a valid value; midnight is 0, not 24.
- If every hour is intended, keep the '*' wildcard instead of an explicit list.
- Unit-test generated/stored cron strings by constructing CronExpression in a test before persisting them.
Example fix
// before
new CronExpression("0 0 24 * * ?"); // 24 is out of range
// after
new CronExpression("0 0 0 * * ?"); // midnight = 0 Defensive patterns
Strategy: validation
Validate before calling
// Reject out-of-range HOUR before building CronExpression
String expr = "0 0 24 * * ?";
String[] f = expr.trim().split("\\s+");
String hourField = (f.length >= 6) ? f[2] : f[1]; // hour position in 5- or 6-field cron
// cheap literal guard; ranges/steps still need a full parse
if (hourField.matches("\\d+") ) {
int h = Integer.parseInt(hourField);
if (h < 0 || h > 23) throw new IllegalArgumentException("hour out of range: " + h);
} Try / catch
try {
CronExpression c = new CronExpression(expr);
} catch (java.text.ParseException e) {
log.warn("Invalid cron '{}': {}", expr, e.getMessage());
} Prevention
- Treat cron HOUR as 0-based 0-23; midnight is 0 not 24.
- Unit-test every generated cron string with new CronExpression(expr).
- Never assemble cron strings from unchecked user input.
When it happens
Trigger: Constructing new CronExpression("0 0 24 * * ?"), or any HOUR field with a literal >23 or <0, a range like "0-26", or a step value whose computed value exceeds 23. Triggered during CronExpression construction (parsing), before the expression is ever used to compute a fire time.
Common situations: Assuming a 1-24 hour clock and typing 24 for midnight (should be 0); migrating schedules from tools that use 1-based hours; dynamically generating cron strings with an off-by-one error in the hour computation.
Related errors
- Day of month values must be between 1 and 31
- Month values must be between 1 and 12
- 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/689be6bc674044e8.
Report an issue: GitHub.