quarkusio/quarkus · error · IllegalStateException
Invalid () expression on:
Error message
Invalid () expression on:
What it means
A @Scheduled member (cron, every, delayed, or overdue grace period) given as a value or config expression could not be parsed into a Duration/Schedule by DurationConverter. The member name is embedded in the message and the original parse exception is chained as the cause.
Source
Thrown at extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java:189
return false;
}
int exprStart = val.indexOf("${");
int exprEnd = -1;
if (exprStart >= 0) {
exprEnd = val.indexOf('}', exprStart + 2);
}
return exprEnd > 0;
}
private static long parseDurationAsMillis(Scheduled scheduled, String value, String memberName) {
return Math.abs(parseDuration(scheduled, value, memberName).toMillis());
}
private static Duration parseDuration(Scheduled scheduled, String value, String memberName) {
try {
return DurationConverter.parseDuration(value);
} catch (Exception e) {
throw new IllegalStateException("Invalid " + memberName + "() expression on: " + scheduled, e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Use a valid duration string with unit, e.g. "10s", "5m", "1h" or ISO-8601 like "PT10S"
- Fix the config value the expression resolves to
- Check the chained cause exception for the exact parse failure
- For cron use a valid cron expression via @Scheduled(cron=...) instead of duration syntax
Example fix
// before @Scheduled(every = "10") // after @Scheduled(every = "10s")
Defensive patterns
Strategy: validation
Validate before calling
try {
java.time.Duration.parse("10s".matches(".*[a-zA-Z].*") ? "PT" + "10s".toUpperCase() : "PT" + "10s" + "S");
} catch (Exception e) { /* invalid duration */ } Try / catch
try { DurationConverter.parseDuration(value); }
catch (Exception e) { throw new IllegalArgumentException("Bad duration: " + value, e); } Prevention
- Always include a unit: 10s, 5m, 1h, or ISO-8601 PT10S
- Test schedule expressions with unit tests before deploying
- Validate config-sourced durations at startup
- Avoid hand-writing durations; reuse constants
When it happens
Trigger: Calling SchedulerUtils.parseOverdueGracePeriod or parseDurationAsMillis with an @Scheduled whose member value is not a valid duration (e.g. "10", "ten seconds", an unexpanded/bad expression).
Common situations: Writing every="10" without a time unit ("10s"); misspelled unit ("5min" vs "5m"); config expression resolving to empty or malformed string; negative or nonsense durations.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- Could not expand value %s in property %s
- Either the 'cron' expression or the 'every' period must be s
- The class (${name}) cannot be created during deployment.
- Can not add converter ${converter.name()} that is not parame
- Converter ${converter.name()} must be parameterized with a s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c3a27a6a869cc853.
Report an issue: GitHub.