jeecgboot/JeecgBoot · error · IllegalArgumentException
Start year must be less than stop year
Error message
Start year must be less than stop year
What it means
Thrown as an IllegalArgumentException during range expansion when the field type is YEAR and the stop (end) year is less than the start year. Unlike other fields (seconds, hours, months, etc.) where a reversed range can wrap around using modulus arithmetic, years cannot wrap, so a reversed year range is treated as an unrecoverable configuration error.
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:1090
}
if (startAt == -1 || startAt == ALL_SPEC_INT) {
startAt = 1970;
}
}
// if the end of the range is before the start, then we need to overflow into
// the next day, month etc. This is done by adding the maximum amount for that
// type, and using modulus max to determine the value being added.
int max = -1;
if (stopAt < startAt) {
switch (type) {
case SECOND : max = 60; break;
case MINUTE : max = 60; break;
case HOUR : max = 24; break;
case MONTH : max = 12; break;
case DAY_OF_WEEK : max = 7; break;
case DAY_OF_MONTH : max = 31; break;
case YEAR : throw new IllegalArgumentException("Start year must be less than stop year");
default : throw new IllegalArgumentException("Unexpected type encountered");
}
stopAt += max;
}
for (int i = startAt; i <= stopAt; i += incr) {
if (max == -1) {
// ie: there's no max to overflow over
set.add(i);
} else {
// take the modulus to get the real value
int i2 = i % max;
// 1-indexed ranges should not include 0, and should include their max
if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) {
i2 = max;
}
View on GitHub (pinned to 96fb33f5ec)
Solutions
- Swap the range bounds so the start year is less than or equal to the stop year.
- If building dynamically, sort or validate the two year values before constructing the range string.
- Consider whether a single year value or '*' is more appropriate than a range.
Example fix
// before String cron = "0 0 0 1 1 ? 2025-2020"; // end < start // after String cron = "0 0 0 1 1 ? 2020-2025"; // start < end
Defensive patterns
Strategy: validation
Validate before calling
// Validate year range: start <= stop
String yearField = fields[6]; // 7th field if present
if (yearField.contains("-")) {
String[] parts = yearField.split("-");
int start = Integer.parseInt(parts[0]);
int stop = Integer.parseInt(parts[1]);
if (stop < start) throw new IllegalArgumentException("Start year must be <= stop year");
} Type guard
boolean isValidYearRange(String yearField) {
if (!yearField.contains("-") || yearField.equals("*")) return true;
String[] parts = yearField.split("-");
try {
return Integer.parseInt(parts[0]) <= Integer.parseInt(parts[1]);
} catch (NumberFormatException e) {
return false;
}
} Try / catch
try {
CronExpression cron = new CronExpression(expr);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Start year must be less than stop year")) {
// swap or fix the year range bounds
}
throw e;
} Prevention
- Ensure the start year is less than or equal to the stop year.
- Validate user-supplied year range inputs at the UI layer.
- Consider using a single year or '*' instead of a range when appropriate.
When it happens
Trigger: A cron expression with an optional 7th field (year) containing a range where the end precedes the start — e.g., year field '2020-2019', '2025-2020', or '2030-2000'.
Common situations: Developer accidentally swaps start and end in a year range; UI form inputs start/end year in wrong order; copy-paste error; dynamic generation where user-selected end year is earlier than start year.
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/e822d06b7bf66ca3.
Report an issue: GitHub.