{"record":{"id":"655cef1e318af24c","repo":"apache/skywalking","slug":"metersystem-unavailable-for-mal-compile-of-source","errorCode":null,"errorMessage":"MeterSystem unavailable for MAL compile of {sourceName}","messagePattern":"MeterSystem unavailable for MAL compile of (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/engine/mal/MalRuleEngine.java","lineNumber":389,"sourceCode":"     * shape. Returns a {@link CompiledMalDSL} carrying the deltas, prior Applied, and the\n     * freshly-registered Applied for the rest of the pipeline.\n     *\n     * <p>Throws {@link MalFileApplier.ApplyException} (wrapped in {@link RuntimeException} for\n     * SPI compatibility) on compile / register failure; the orchestrator catches and routes\n     * to {@link #rollback}.\n     */\n    @Override\n    public CompiledDSL compile(final RuntimeRuleManagementDAO.RuntimeRuleFile file,\n                               final Classification classification,\n                               final DSLClassLoaderManager.Kind kind,\n                               final MalApplyContext ctx) {\n        final String key = DSLScriptKey.key(file.getCatalog(), file.getName());\n        final String sourceName = file.getCatalog() + \"/\" + file.getName();\n        final String newHash = ContentHash\n            .sha256Hex(file.getContent());\n        final MalFileApplier applier = resolveApplier();\n        if (applier == null) {\n            throw new IllegalStateException(\"MeterSystem unavailable for MAL compile of \"\n                + sourceName);\n        }\n        final MalFileApplier.Applied oldApplied = appliedFor(ctx.getRules(), key);\n\n        // FILTER_ONLY fast path: no shape-break drop, no DDL move, no alarm reset, no\n        // classloader retire. Just produce the freshly-compiled Applied and let commit do\n        // the in-memory swap. The classifier already ran — engines don't re-classify here.\n        if (classification == Classification.FILTER_ONLY) {\n            final MalFileApplier.Applied fresh;\n            try {\n                fresh = applier.apply(\n                    file.getContent(), sourceName, newHash, ctx.getStorageOpt(), kind);\n            } catch (final MalFileApplier.ApplyException ae) {\n                // Engine-internal partial rollback: undo whatever this attempt managed to\n                // register before the throw. Old appliedMal[key] is untouched — it's still\n                // serving — so removing the partial set is the only mutation needed.\n                applier.remove(ae.getPartiallyRegistered(), ctx.getStorageOpt());\n                throw new EngineCompileException(ae);","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/engine/mal/MalRuleEngine.java#L371-L407","documentation":"MalRuleEngine.compile throws IllegalStateException when resolveApplier() fails to obtain the MeterSystem needed to build a MalFileApplier. MeterSystem is a core-module service the MAL engine looks up at compile time; null means CoreModule (or its meter service) is not available on this node at that moment — a module wiring/initialization defect rather than a rule-content problem.","triggerScenarios":"Any runtime-rule operation that reaches MalRuleEngine.compile (apply/update of a MAL file) on a node where the CoreModule service lookup returns null — typically a custom packaging without core, or a compile request racing module initialization at startup. The check runs per compile, so the first MAL rule operation after a bad boot is what surfaces it.","commonSituations":"Custom minimal OAP packaging (tools/mock providers) that boots the runtime-rule module without the core meter service; Core module still initializing when a queued runtime-rule apply arrives at startup; Mis-ordered module dependencies after refactoring requiredModules()","solutions":["Verify CoreModule and its MeterSystem service are started on this node (check module list and startup logs) and restart if the config was wrong","Audit the runtime-rule provider's requiredModules() to guarantee core availability before compiles","Purge orphaned MAL runtime rules if this node is intentionally metric-free","If it was a startup race, re-submit the rule operation after boot completes"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"final boolean malReady = moduleManager.find(CoreModule.NAME) != null\n    && getManager().find(CoreModule.NAME).provider().getService(MeterSystem.class) != null;\nif (!malReady) deferOrReject(\"MAL compile needs CoreModule MeterSystem\");","typeGuard":null,"tryCatchPattern":"catch (IllegalStateException e) when 'MeterSystem unavailable': treat as node misconfiguration — verify CoreModule is booted (startup logs), restart, and re-submit the rule operation; don't blind-retry during the same boot.","preventionTips":["Declare core-module dependency in requiredModules() of the runtime-rule provider so boot order guarantees MeterSystem","Keep queued rule operations out of the startup window — gate on module-ready health checks","Never ship a runtime-rule-enabled packaging without the core meter service"],"tags":["module-wiring","mal","meter-system","configuration"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}