jeecgboot/JeecgBoot · error · ParseException
Minute and Second values must be between 0 and 59
Error message
Minute and Second values must be between 0 and 59
What it means
Thrown by addToSet when a value (or range end) for the SECOND or MINUTE field is less than 0 or greater than 59, unless the value is ALL_SPEC_INT (the internal sentinel for '*'). This guards the final value that gets stored in the TreeSet after all parsing and range resolution, so it catches both raw values and computed range endpoints.
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:988
return i;
}
protected int findNextWhiteSpace(int i, String s) {
for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) {
}
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);View on GitHub (pinned to 96fb33f5ec)
Solutions
- Ensure all second and minute values are integers from 0 to 59.
- Check range endpoints: '0-59' is valid, '0-60' is not.
- Validate dynamic cron components against field bounds before constructing the expression.
Example fix
// before String cron = "60 * * * * ?"; // 60 is invalid for seconds // after String cron = "0/30 * * * * ?"; // every 30 seconds
Defensive patterns
Strategy: validation
Validate before calling
// Validate seconds/minutes field values are 0-59
void validateSecondOrMinute(String field) {
for (String token : field.split(",")) {
token = token.split("[/\\-]")[0]; // take base value
if (!token.equals("*") && !token.equals("?")) {
int val = Integer.parseInt(token);
if (val < 0 || val > 59) throw new IllegalArgumentException("Value must be 0-59: " + val);
}
}
} Type guard
boolean isValidSecondOrMinute(String field) {
for (String token : field.split(",")) {
if (token.equals("*") || token.equals("?")) continue;
try {
for (String part : token.split("[/\\-]")) {
int val = Integer.parseInt(part);
if (val < 0 || val > 59) return false;
}
} catch (NumberFormatException e) { return false; }
}
return true;
} Try / catch
try {
CronExpression cron = new CronExpression(expr);
} catch (ParseException e) {
if (e.getMessage().contains("Minute and Second values must be between 0 and 59")) {
// fix the seconds or minutes field value
}
throw e;
} Prevention
- Keep second and minute values in the 0–59 range.
- Use 0 for the start, not 60 or 1 for the beginning of the minute.
- Bounds-check dynamically generated field values.
When it happens
Trigger: A cron expression with a seconds or minutes field containing a value like 60, 99, -1, or a range like 0–70 — e.g., seconds field '60', minutes field '45,75', or range '10-65'. Also triggered if a step computation overflows, though the range check in setAddition usually catches that earlier.
Common situations: Developer uses 60 as a minute/second value (should be 0); off-by-one in range bounds; dynamic value injection without bounds checking; confusion between 0-based and 1-based fields.
Related errors
- Day-of-Week values must be between 1 and 7
- 'L' option is not valid here. (pos=${i})
- 'W' option is not valid here. (pos=${i})
- The 'W' option does not make sense with values larger than 3
- '#' option is not valid here. (pos=${i})
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/df451e1436a6de62.
Report an issue: GitHub.