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

  1. Ensure all second and minute values are integers from 0 to 59.
  2. Check range endpoints: '0-59' is valid, '0-60' is not.
  3. 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

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


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/df451e1436a6de62. Report an issue: GitHub.