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

  1. Verify each file in the malFiles list exists under malPath (the IOException cause names the file)
  2. Validate the meter YAML against the shipped log-mal-rules examples (top-level 'rules:' list, correct metric expression syntax)
  3. Remove stale entries from the malFiles comma list
  4. 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

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


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/83cc3ce9bdc0f520. Report an issue: GitHub.