apache/skywalking · error · UnexpectedException
Some configuration files of enabled rules are not found, ena
Error message
Some configuration files of enabled rules are not found, enabled rules: {} What it means
UnexpectedException thrown by the Rules loader when one or more rule names listed in the 'forceEnabledRules'/'enabledRules' configuration have no corresponding file on disk (their entry in formedEnabledRules stayed false after the directory walk). The OAP refuses to start with a partially loaded ruleset and reports exactly which enabled rules are missing.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/prometheus/rule/Rules.java:134
}).forEach(p -> {
final String rel = root.relativize(p).toString();
final String ruleName = rel.substring(0, rel.lastIndexOf('.'));
// Keep the actual extension: both .yaml and .yml load, and synthesising .yaml for
// a .yml rule points the provenance at a file that does not exist.
diskPaths.put(ruleName, rel);
try {
diskBytes.put(ruleName, Files.readAllBytes(p));
} catch (IOException e) {
throw new UnexpectedException("Load rule file " + p.getFileName() + " failed", e);
}
});
}
if (formedEnabledRules.containsValue(false)) {
List<String> rulesNotFound = formedEnabledRules.keySet().stream()
.filter(rule -> !formedEnabledRules.get(rule))
.collect(Collectors.toList());
throw new UnexpectedException("Some configuration files of enabled rules are not found, enabled rules: " + rulesNotFound);
}
// Merge with classpath-discovered resolvers (runtime-rule DB, plus any future
// priority-ranked source). ACTIVE substitutes existing disk entries; INACTIVE
// drops them. Resolver-only rules (no disk twin) are NOT merged here — they're
// applied by RuleSync.runOnce post-seal via the dynamic layer channel.
final Map<String, byte[]> merged = useInstalledManager
? RuleSetMerger.merge(path, diskBytes)
: RuleSetMerger.merge(path, diskBytes, manager);
return merged.entrySet().stream()
.map(e -> parseRule(path, e.getKey(), diskPaths.get(e.getKey()), e.getValue()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
private static Rule parseRule(final String rulesetDir, final String ruleName,
final String relPath, final byte[] bytes) {View on GitHub (pinned to 102af09b4a)
Solutions
- Check the exception message — it lists the exact missing rule names; verify each has a matching .yaml/.yml in the rules directory
- Fix typos/casing in the enabled-rules entries in application.yml (rule name = file name without extension)
- If the rule was removed in the newer OAP version, delete the stale entry from enabledRules or migrate to the replacement rule
- Verify the meter-analyzer rulesPath setting resolves to the directory that actually contains the rule files (in the running container, not just in the repo)
Example fix
# before (application.yml)
mal-rule:
enabledRules:
- spring-serv
# after
mal-rule:
enabledRules:
- spring-service Defensive patterns
Strategy: validation
Validate before calling
// Before start: every enabled rule must have a file
Set<String> onDisk = Files.list(rulesPath).map(p -> p.getFileName().toString().replaceAll("\\.(ya?ml)$", "")).collect(Collectors.toSet());
for (String r : configuredEnabledRules) {
if (!onDisk.contains(r)) throw new IllegalStateException("Missing rule file for: " + r);
} Prevention
- Treat rule names as file-name contracts; validate config against the directory in CI
- After OAP upgrades, diff the enabledRules list against the shipped rules directory
- Use exact file-name casing (no spaces/underscores drift)
When it happens
Trigger: Config lists a rule name (e.g. 'vm' or 'k8s-cp') in enabledRules/forceEnabledRules but no <rule>.yaml/.yml exists in the resolved rules directory; also when the file name casing or extension doesn't match, or the rulesPath points at the wrong directory.
Common situations: Upgrading OAP where a rule was renamed or removed but application.yml still enables it; typos in rule names in application.yml; wrong meter-analyzer rulesPath (empty default path vs custom path); running a stripped-down distribution that ships fewer built-in rule files.
Related errors
- Load meter analyzer configs failed
- {slot} value '{numText}' exceeds the supported range (must f
- Unclosed interpolation in: {s}
- decorate() should be invoked after service()
- Failed to compile MAL expression for metric: {}, expression:
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/fa60161fde376652.
Report an issue: GitHub.