flowable/flowable-engine · error · ParseException

Support for specifying both a day-of-week AND a day-of-month

Error message

Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.

What it means

This cron dialect does not allow specifying both day-of-month and day-of-week as restricted values; one of them must be '?'. buildExpression computes dayOfMSpec/dayOfWSpec from whether the sets contain NO_SPEC, and throws this ParseException when both are specified (and also when neither is, given the nested condition structure).

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java:532

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

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

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

            // Copying the logic from the UnsupportedOperationException below
            boolean dayOfMSpec = !dom.contains(NO_SPEC);
            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);
                }
            }
        } catch (ParseException pe) {
            throw pe;
        } catch (Exception e) {
            throw new ParseException("Illegal cron expression format (" + e + ")", 0);
        }
    }

    protected int storeExpressionVals(int pos, String s, int type) throws ParseException {

        int incr = 0;
        int i = skipWhiteSpace(pos, s);
        if (i >= s.length()) {
            return i;
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Replace the less relevant day field with '?': '0 0 12 15 * ?' or '0 0 12 ? * FRI'
  2. Decide whether the schedule means 'day of month' or 'day of week' and keep only one
  3. If OR semantics are needed, create two schedules and union the triggers
  4. Note this differs from standard Unix cron — document the dialect for config authors

Example fix

// before
String cron = "0 0 12 15 * FRI"; // both dom and dow restricted
// after
String cron = "0 0 12 15 * ?"; // 15th of every month (or '0 0 12 ? * FRI' for Fridays)
Defensive patterns

Strategy: validation

Validate before calling

boolean domSet = !fields[2].equals("?") && !fields[2].equals("*");
boolean dowSet = !fields[5].equals("?") && !fields[5].equals("*");
if (domSet && dowSet) throw new IllegalArgumentException("specify only one of day-of-month or day-of-week, use '?' for the other");

Try / catch

try { new CronExpression(expr, clockReader); }
catch (ParseException e) { if (e.getMessage().contains("day-of-week AND a day-of-month")) { /* set one field to '?' */ } throw e; }

Prevention

When it happens

Trigger: new CronExpression(expr, clockReader) where the 3rd and 6th fields both contain concrete values, e.g. '0 0 12 15 * FRI'; the same path is hit via readObject during deserialization.

Common situations: Users writing '0 0 0 1 * MON' expecting OR semantics (unix cron behavior) instead of the Quartz rule; migrating expressions from Unix cron to Flowable/Quartz cron without changing the day fields.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/91c837ab457dcccb. Report an issue: GitHub.