{"record":{"id":"fa60161fde376652","repo":"apache/skywalking","slug":"some-configuration-files-of-enabled-rules-are-not","errorCode":null,"errorMessage":"Some configuration files of enabled rules are not found, enabled rules: {}","messagePattern":"Some configuration files of enabled rules are not found, enabled rules: (.+?)","errorType":"exception","errorClass":"UnexpectedException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/prometheus/rule/Rules.java","lineNumber":134,"sourceCode":"            }).forEach(p -> {\n                final String rel = root.relativize(p).toString();\n                final String ruleName = rel.substring(0, rel.lastIndexOf('.'));\n                // Keep the actual extension: both .yaml and .yml load, and synthesising .yaml for\n                // a .yml rule points the provenance at a file that does not exist.\n                diskPaths.put(ruleName, rel);\n                try {\n                    diskBytes.put(ruleName, Files.readAllBytes(p));\n                } catch (IOException e) {\n                    throw new UnexpectedException(\"Load rule file \" + p.getFileName() + \" failed\", e);\n                }\n            });\n        }\n\n        if (formedEnabledRules.containsValue(false)) {\n            List<String> rulesNotFound = formedEnabledRules.keySet().stream()\n                    .filter(rule -> !formedEnabledRules.get(rule))\n                    .collect(Collectors.toList());\n            throw new UnexpectedException(\"Some configuration files of enabled rules are not found, enabled rules: \" + rulesNotFound);\n        }\n\n        // Merge with classpath-discovered resolvers (runtime-rule DB, plus any future\n        // priority-ranked source). ACTIVE substitutes existing disk entries; INACTIVE\n        // drops them. Resolver-only rules (no disk twin) are NOT merged here — they're\n        // applied by RuleSync.runOnce post-seal via the dynamic layer channel.\n        final Map<String, byte[]> merged = useInstalledManager\n            ? RuleSetMerger.merge(path, diskBytes)\n            : RuleSetMerger.merge(path, diskBytes, manager);\n\n        return merged.entrySet().stream()\n            .map(e -> parseRule(path, e.getKey(), diskPaths.get(e.getKey()), e.getValue()))\n            .filter(Objects::nonNull)\n            .collect(Collectors.toList());\n    }\n\n    private static Rule parseRule(final String rulesetDir, final String ruleName,\n                                  final String relPath, final byte[] bytes) {","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/prometheus/rule/Rules.java#L116-L152","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"# before (application.yml)\nmal-rule:\n  enabledRules:\n    - spring-serv\n# after\nmal-rule:\n  enabledRules:\n    - spring-service","handlingStrategy":"validation","validationCode":"// Before start: every enabled rule must have a file\nSet<String> onDisk = Files.list(rulesPath).map(p -> p.getFileName().toString().replaceAll(\"\\\\.(ya?ml)$\", \"\")).collect(Collectors.toSet());\nfor (String r : configuredEnabledRules) {\n    if (!onDisk.contains(r)) throw new IllegalStateException(\"Missing rule file for: \" + r);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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)"],"tags":["mal","rule-config","configuration","startup","oap"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}