apache/skywalking · error · IllegalArgumentException
expression can't be empty
Error message
expression can't be empty
What it means
IllegalArgumentException thrown by RulesReader while loading alarm-settings.yml when a `*_rule` entry has an empty or missing `expression` key. Every alarm rule must carry an expression; the reader fails fast during YAML parsing so the OAP does not start (or the dynamic config update fails) with a half-initialized rule set.
Source
Thrown at oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java:105
}
/**
* Read rule config into {@link AlarmRule}
*/
private void readRulesConfig(Rules rules) {
Map rulesData = (Map) yamlData.get("rules");
if (rulesData == null) {
return;
}
rules.setRules(new ArrayList<>());
rulesData.forEach((k, v) -> {
if (((String) k).endsWith("_rule")) {
AlarmRule alarmRule = new AlarmRule(moduleManager);
alarmRule.setAlarmRuleName((String) k);
Map settings = (Map) v;
Object expression = settings.get("expression");
if (StringUtil.isEmpty((String) expression)) {
throw new IllegalArgumentException("expression can't be empty");
}
try {
alarmRule.setExpression(expression.toString());
} catch (IllegalExpressionException e) {
throw new IllegalArgumentException(e);
}
alarmRule.setIncludeNames((ArrayList) settings.getOrDefault("include-names", new ArrayList(0)));
alarmRule.setExcludeNames((ArrayList) settings.getOrDefault("exclude-names", new ArrayList(0)));
alarmRule.setIncludeNamesRegex((String) settings.getOrDefault("include-names-regex", ""));
alarmRule.setExcludeNamesRegex((String) settings.getOrDefault("exclude-names-regex", ""));
alarmRule.setPeriod((Integer) settings.getOrDefault("period", 1));
// How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.
alarmRule.setSilencePeriod((Integer) settings.getOrDefault("silence-period", alarmRule.getPeriod()));
alarmRule.setRecoveryObservationPeriod((Integer) settings.getOrDefault("recovery-observation-period",
0));
alarmRule.setMessage(
(String) settings.getOrDefault("message", "Alarm caused by Rule " + alarmRule
.getAlarmRuleName()));View on GitHub (pinned to 102af09b4a)
Solutions
- Add a valid MQE expression to the rule entry, e.g. `expression: sum(service_resp_time > 1000) >= 3`.
- Check YAML indentation — `expression` must be a direct child of the rule name, same level as `period`, `threshold`, etc.
- If the rule is intentionally disabled, remove or rename the key so it does not end with `_rule` instead of leaving it expression-less.
- Validate alarm-settings.yml with a YAML linter before deploying; the exception aborts the entire rules load, not just this rule.
Example fix
# before
rules:
service_sla_rule:
threshold: 1
# after
rules:
service_sla_rule:
expression: sum(service_sla < 90) >= 3
threshold: 1 Defensive patterns
Strategy: validation
Validate before calling
# YAML pre-check before deploying alarm-settings.yml
python3 -c "
import yaml,sys
rules = yaml.safe_load(open('alarm-settings.yml')).get('rules') or {}
for name, s in rules.items():
if name.endswith('_rule') and not (s.get('expression') or '').strip():
sys.exit(f'{name}: expression missing/empty')
" Prevention
- Template alarm-settings.yml with required-field linting (yamllint plus a schema check).
- Treat expression as a mandatory key in any internal rule authoring UI or CRD schema.
- Never comment out expression to 'disable' a rule — delete or rename the rule key instead.
When it happens
Trigger: A rules map entry whose key ends with `_rule` but whose settings map has no `expression` key, or expression: "" (empty string / null after YAML parsing). RulesReader calls alarmRule.setExpression(expression.toString()) only after StringUtil.isEmpty passes, so any blank value hits this branch.
Common situations: Creating a new rule by copy-paste and deleting the expression line; YAML indentation that accidentally places `expression` under a sibling key; setting expression: null while templating alarm-settings via Helm/Kustomize; a commented-out line (`#expression: ...`) that removes the only expression.
Related errors
- Expression: {expression} is not a SINGLE_VALUE result expres
- Failed to load LAL config rules
- LAL rule {ruleName} layerDefinitions entry rejected: {def}
- Failed to load MAL rules
- Load rule {} failed
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/e53d0e1665dc7d2b.
Report an issue: GitHub.