apache/skywalking · critical · ModuleStartException
Failed to load MAL rules
Error message
Failed to load MAL rules
What it means
Thrown by the log-analyzer module when loading MAL (meter) rules referenced by log rules: malConfigs() splits the malFiles config on commas and calls Rules.loadRules(malPath, files); any IOException (missing path, unreadable file, YAML structure error surfaced as IO) is wrapped in ModuleStartException and fails provider start. This is the meter-analyzer loader reused for the log-mal-rules catalog, not the LAL loader.
Source
Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/LogAnalyzerModuleConfig.java:69
private String malFiles;
private List<Rule> meterConfigs;
public List<String> lalFiles() {
return Splitter.on(",").omitEmptyStrings().trimResults().splitToList(Strings.nullToEmpty(getLalFiles()));
}
public List<Rule> malConfigs() throws ModuleStartException {
if (nonNull(meterConfigs)) {
return meterConfigs;
}
final List<String> files = Splitter.on(",")
.omitEmptyStrings()
.splitToList(Strings.nullToEmpty(getMalFiles()));
try {
meterConfigs = Rules.loadRules(getMalPath(), files);
} catch (IOException e) {
throw new ModuleStartException("Failed to load MAL rules", e);
}
return meterConfigs;
}
}
View on GitHub (pinned to 102af09b4a)
Solutions
- Verify each file in the malFiles list exists under malPath (the IOException cause names the file)
- Validate the meter YAML against the shipped log-mal-rules examples (top-level 'rules:' list, correct metric expression syntax)
- Remove stale entries from the malFiles comma list
- Check the nested IOException cause — it distinguishes missing-file from parse failures
Example fix
# before malFiles: my-rules.yaml,old-rules.yaml # old-rules.yaml deleted # after malFiles: my-rules.yaml
Defensive patterns
Strategy: validation
Validate before calling
# Pre-start check: every listed file exists under malPath # IFS=',' ; for f in $MAL_FILES; do test -f "$MAL_PATH/$f" || echo "missing: $MAL_PATH/$f"; done
Try / catch
try {
List<Rule> rules = config.malConfigs();
} catch (ModuleStartException e) {
// IOException cause names the file; fix path or YAML, then restart
} Prevention
- Keep the malFiles list in sync with actually shipped files
- Validate meter YAML with the same schema as shipped log-mal-rules
- Add a packaging check that every configured rule file is present in the dist
When it happens
Trigger: malPath/malFiles under the log-analyzer provider pointing to missing or unreadable files; malformed meter-analyzer YAML (rules not a list, bad indentation) causing a load failure; files listed in malFiles that don't exist under malPath.
Common situations: Adding a custom meter rule file for log-derived metrics but forgetting to ship it into the image; typo in the malFiles comma list; copying log-mal-rules config between versions where the rule schema changed.
Related errors
- Failed to load LAL config rules
- LAL rule {ruleName} layerDefinitions entry rejected: {def}
- tag() reads LogData tags but the input type is {inputTypeNam
- Failed to compile LAL expression: {dsl}
- Failed to create LAL listener factory.
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/83cc3ce9bdc0f520.
Report an issue: GitHub.