alibaba/spring-cloud-alibaba · 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 in addToSet when a SECOND or MINUTE value (or range end) is outside 0-59, unless it is the ALL_SPEC wildcard sentinel (guard at CronExpression.java:771-775). This catches out-of-range literal values that slipped past the earlier step checks.

Source

Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java:768

		return i;
	}

	protected int findNextWhiteSpace(int i, final String s) {
		for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) {
			// empty
		}

		return i;
	}

	protected void addToSet(final int val, final int end, int incr, final int type)
			throws ParseException {

		final 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) {

View on GitHub (pinned to 115d590110)

Solutions

  1. Keep seconds and minutes in 0-59, e.g. '60' -> '0' or '59'.
  2. For 'every minute at second 0' use '0 * * * * ?', not '60'.
  3. Recount the six fields so values land in the correct position.

Example fix

// before
new CronExpression("60 * * * * ?");
// after
new CronExpression("0 * * * * ?"); // at second 0 of every minute
Defensive patterns

Strategy: validation

Validate before calling

// Seconds(0) and minutes(1) literals must be 0..59 (ignoring '*' and '?').
static boolean timeFieldsInRange(String[] fields) {
    if (fields.length < 3) return false;
    return inRange(fields[0], 0, 59) && inRange(fields[1], 0, 59);
}
private static boolean inRange(String f, int lo, int hi) {
    if (f.equals("*") || f.equals("?")) return true;
    for (String part : f.split("[-,/LW#]")) {
        if (part.isEmpty()) continue;
        try { int v = Integer.parseInt(part); if (v < lo || v > hi) return false; }
        catch (NumberFormatException e) { /* names handled elsewhere */ }
    }
    return true;
}

Try / catch

try {
    CronExpression cron = new CronExpression(raw);
} catch (ParseException e) {
    throw new IllegalArgumentException("Invalid cron expression: " + raw, e);
}

Prevention

When it happens

Trigger: `new CronExpression("60 * * * * ?")` (seconds=60), or `0 60 * * * ?` (minutes=60), or a range like `0 0-60 * * * ?` (end=60).

Common situations: Using 60 for 'top of the minute' (invalid; seconds are 0-59), a 1-based minute assumption, or a field-shift placing a larger value into seconds/minutes.

Related errors


AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14). Data as JSON: /api/errors/5e3d4f139e61e627. Report an issue: GitHub.