xuxueli/xxl-job · error · ParseException
Unexpected character: {}
Error message
Unexpected character: {} What it means
This is the catch-all for any character in a cron field that the parser does not recognize. The parser handles '?', '*', '/', 'L', and digits 0-9; any other character (e.g., letters other than 'L', symbols like '&', '%', '!') triggers this error.
Source
Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:720
}
return i;
} else if (c >= '0' && c <= '9') {
int val = Integer.parseInt(String.valueOf(c));
i++;
if (i >= s.length()) {
addToSet(val, -1, -1, type);
} else {
c = s.charAt(i);
if (c >= '0' && c <= '9') {
ValueSet vs = getValue(val, s, i);
val = vs.value;
i = vs.pos;
}
i = checkNext(i, s, val, type);
return i;
}
} else {
throw new ParseException("Unexpected character: " + c, i);
}
return i;
}
private void checkIncrementRange(int incr, int type, int idxPos) throws ParseException {
if (incr > 59 && (type == SECOND || type == MINUTE)) {
throw new ParseException("Increment >= 60 : " + incr, idxPos);
} else if (incr > 23 && (type == HOUR)) {
throw new ParseException("Increment >= 24 : " + incr, idxPos);
} else if (incr > 31 && (type == DAY_OF_MONTH)) {
throw new ParseException("Increment >= 31 : " + incr, idxPos);
} else if (incr > 7 && (type == DAY_OF_WEEK)) {
throw new ParseException("Increment >= 7 : " + incr, idxPos);
} else if (incr > 12 && (type == MONTH)) {
throw new ParseException("Increment >= 12 : " + incr, idxPos);
}
}View on GitHub (pinned to e74c784f68)
Solutions
- Inspect the cron string for stray or non-ASCII characters and remove them.
- Replace named-day or macro syntax with Quartz-compatible numeric cron tokens.
- Run the raw string through a character-level check to detect non-printable characters before parsing.
Example fix
// before "0 0 0 & * ?" // after "0 0 0 * * ?"
Defensive patterns
Strategy: validation
Validate before calling
// Only allow known cron characters in each field
String allowed = "0123456789*/-?LW#,";
for (char ch : cron.toCharArray()) {
if (!Character.isWhitespace(ch) && allowed.indexOf(ch) == -1) {
throw new IllegalArgumentException("Invalid cron character: '" + ch + "'");
}
} Type guard
boolean hasOnlyCronChars(String cron) {
for (char c : cron.toCharArray()) {
if (!Character.isWhitespace(c) && "0123456789*/-?LW#,".indexOf(c) == -1) return false;
}
return true; Try / catch
try {
new CronExpression(sanitizedCron);
} catch (ParseException e) {
if (e.getMessage().contains("Unexpected character")) {
// strip non-cron characters and re-validate
}
} Prevention
- Sanitize cron input to strip non-ASCII and invisible characters.
- Provide a cron input widget that restricts typed characters to the valid set.
- Test cron strings from external sources (APIs, config files) before parsing.
When it happens
Trigger: A cron field containing an invalid character such as '0 & * * * ?' (ampersand in seconds), 'x * * * * ?', or any stray symbol. The else branch at line 720 fires when none of the preceding character checks match.
Common situations: Encoding issues, invisible characters pasted from a rich-text source, or using a non-Quartz cron dialect that uses different syntax (e.g., '@daily' macro or named days like 'MON' without proper field context).
Related errors
- '/' must be followed by an integer.
- Unexpected end of string.
- 'L' option is not valid here. (pos={})
- Unexpected character '{}' after '/'
- '?' can only be specified for Day-of-Month -OR- Day-of-Week.
AI-assisted analysis of xuxueli/xxl-job@e74c784f68 (2026-08-14).
Data as JSON: /api/errors/3305a50cfa6a0a76.
Report an issue: GitHub.