alibaba/spring-cloud-alibaba · error · ParseException

Unexpected end of expression.

Error message

Unexpected end of expression.

What it means

Thrown at the end of buildExpression if fewer than six whitespace-separated fields were parsed (exprOn, the field counter, did not advance past DAY_OF_WEEK). This CronExpression expects six mandatory fields — second minute hour day-of-month month day-of-week — with an optional seventh (year). Providing too few fields yields ParseException 'Unexpected end of expression.'.

Source

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

				// throw an exception if L is used with other days of the week
				if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
					throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1);
				}
				if (exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') + 1) != -1) {
					throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1);
				}

				final StringTokenizer vTok = new StringTokenizer(expr, ",");
				while (vTok.hasMoreTokens()) {
					final String v = vTok.nextToken();
					storeExpressionVals(0, v, exprOn);
				}

				exprOn++;
			}

			if (exprOn <= DAY_OF_WEEK) {
				throw new ParseException("Unexpected end of expression.",
						expression.length());
			}

			if (exprOn <= YEAR) {
				storeExpressionVals(0, "*", YEAR);
			}

			final TreeSet<Integer> dow = getSet(DAY_OF_WEEK);
			final TreeSet<Integer> dom = getSet(DAY_OF_MONTH);

			// Copying the logic from the UnsupportedOperationException below
			final boolean dayOfMSpec = !dom.contains(NO_SPEC);
			final boolean dayOfWSpec = !dow.contains(NO_SPEC);

			if (!dayOfMSpec || dayOfWSpec) {
				if (!dayOfWSpec || dayOfMSpec) {
					throw new ParseException(
							"Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);

View on GitHub (pinned to 115d590110)

Solutions

  1. Rewrite the cron in 6-field Quartz form: prepend a seconds field and ensure both day-of-month and day-of-week fields are present (use '?' for the one you don't constrain).
  2. For 'daily at 09:00' use '0 0 9 * * ?' (sec=0 min=0 hour=9 dom=* month=* dow=?).
  3. Validate field count == 6 or 7 before parsing.

Example fix

# before (5-field Unix cron -> too few fields)
0 9 * * *

# after (6-field Quartz form)
0 0 9 * * ?
Defensive patterns

Strategy: try-catch

Validate before calling

static void requireSixOrSevenFields(String cron) {
    int n = cron.trim().split("\\s+").length;
    if (n < 6 || n > 7) {
        throw new IllegalArgumentException(
            "cron must have 6 or 7 fields, got " + n);
    }
}
// then new com.alibaba.cloud.scheduling.schedulerx.util.CronExpression(cron)

Try / catch

try {
    new CronExpression(cron);
} catch (ParseException e) {
    // "Unexpected end of expression." -> too few fields
    log.error("Cron '{}' has too few fields (need 6): {}", cron, e.getMessage());
}

Prevention

When it happens

Trigger: A cron with fewer than six fields, e.g. traditional 5-field Unix cron '0 9 * * *' (missing seconds and the '?' for one day field). The check at CronExpression.java:290-293 throws when exprOn <= DAY_OF_WEEK after consuming all tokens.

Common situations: Pasting a 5-field Linux crontab entry into a Quartz/SchedulerX config; trailing whitespace trimming that merges fields; an expression truncated by a templating or escaping bug.

Related errors


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