{"record":{"id":"9795c4699a3fda9f","repo":"xuxueli/xxl-job","slug":"minute-and-second-values-must-be-between-0-and-59","errorCode":null,"errorMessage":"Minute and Second values must be between 0 and 59","messagePattern":"Minute and Second values must be between 0 and 59","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":988,"sourceCode":"\n        return i;\n    }\n\n    protected int findNextWhiteSpace(int i, String s) {\n        for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\\t'); i++) {\n        }\n\n        return i;\n    }\n\n    protected void addToSet(int val, int end, int incr, int type)\n            throws ParseException {\n\n        TreeSet<Integer> set = getSet(type);\n\n        if (type == SECOND || type == MINUTE) {\n            if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Minute and Second values must be between 0 and 59\",\n                        -1);\n            }\n        } else if (type == HOUR) {\n            if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Hour values must be between 0 and 23\", -1);\n            }\n        } else if (type == DAY_OF_MONTH) {\n            if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)\n                    && (val != NO_SPEC_INT)) {\n                throw new ParseException(\n                        \"Day of month values must be between 1 and 31\", -1);\n            }\n        } else if (type == MONTH) {\n            if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Month values must be between 1 and 12\", -1);","sourceCodeStart":970,"sourceCodeEnd":1006,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L970-L1006","documentation":"In addToSet, for the seconds or minutes field (type SECOND or MINUTE), the value must be between 0 and 59 inclusive, and the range end must also be <= 59. The only exception is ALL_SPEC_INT (99), which represents '*'. This error fires for any out-of-range value or range endpoint.","triggerScenarios":"A cron expression like '60 * * * * ?' (seconds=60), '0-60 * * * * ?' (range end 60), or '0 70 * * * ?' (minutes=70). The check at line 987 tests (val < 0 || val > 59 || end > 59) && val != ALL_SPEC_INT.","commonSituations":"Off-by-one errors when generating second/minute values, using 1-indexed logic on a 0-indexed field, or a UI that allows entering 60 as a maximum.","solutions":["Clamp second and minute values to 0-59 before constructing the cron string.","Use '*' if you mean 'every second/minute' rather than a large number.","Validate the cron expression with a dedicated validator before passing it to the CronExpression constructor."],"exampleFix":"// before\n\"60 * * * * ?\"\n// after\n\"0/30 * * * * ?\"","handlingStrategy":"validation","validationCode":"// Validate seconds (field 0) and minutes (field 1) values are 0-59\nString[] parts = cron.trim().split(\"\\\\s+\");\nfor (int idx : new int[]{0, 1}) {\n    if (parts.length > idx && !parts[idx].equals(\"*\") && !parts[idx].equals(\"?\")) {\n        String numStr = parts[idx].replaceAll(\"[^0-9].*\", \"\");\n        if (!numStr.isEmpty()) {\n            int val = Integer.parseInt(numStr);\n            if (val < 0 || val > 59) throw new IllegalArgumentException(\"Second/minute value must be 0-59: \" + val);\n        }\n    }\n}","typeGuard":"boolean isValidSecondMinuteValue(String field) {\n    if (\"*\".equals(field) || \"?\".equals(field)) return true;\n    try {\n        int val = Integer.parseInt(field.replaceAll(\"[^0-9].*\", \"\"));\n        return val >= 0 && val <= 59;\n    } catch (NumberFormatException e) { return false; }","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"Minute and Second values must be between 0 and 59\")) {\n        // clamp the value to 0-59 and retry\n    }\n}","preventionTips":["Seconds and minutes are 0-indexed (0-59), not 1-indexed.","Clamp second/minute values to 0-59 before building the cron expression.","Use '*' for 'every second/minute' rather than entering a large number."],"tags":["cron","validation","range","seconds","minutes"],"backgroundTag":null,"analyzedSha":"e74c784f68f81fa89cb350913ef15794865d7b12","analyzedAt":"2026-08-14T04:22:43.715Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}