apache/skywalking · critical · IllegalStateException
MeterSystem unavailable for MAL compile of {sourceName}
Error message
MeterSystem unavailable for MAL compile of {sourceName} What it means
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.
Source
Thrown at oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/engine/mal/MalRuleEngine.java:389
* shape. Returns a {@link CompiledMalDSL} carrying the deltas, prior Applied, and the
* freshly-registered Applied for the rest of the pipeline.
*
* <p>Throws {@link MalFileApplier.ApplyException} (wrapped in {@link RuntimeException} for
* SPI compatibility) on compile / register failure; the orchestrator catches and routes
* to {@link #rollback}.
*/
@Override
public CompiledDSL compile(final RuntimeRuleManagementDAO.RuntimeRuleFile file,
final Classification classification,
final DSLClassLoaderManager.Kind kind,
final MalApplyContext ctx) {
final String key = DSLScriptKey.key(file.getCatalog(), file.getName());
final String sourceName = file.getCatalog() + "/" + file.getName();
final String newHash = ContentHash
.sha256Hex(file.getContent());
final MalFileApplier applier = resolveApplier();
if (applier == null) {
throw new IllegalStateException("MeterSystem unavailable for MAL compile of "
+ sourceName);
}
final MalFileApplier.Applied oldApplied = appliedFor(ctx.getRules(), key);
// FILTER_ONLY fast path: no shape-break drop, no DDL move, no alarm reset, no
// classloader retire. Just produce the freshly-compiled Applied and let commit do
// the in-memory swap. The classifier already ran — engines don't re-classify here.
if (classification == Classification.FILTER_ONLY) {
final MalFileApplier.Applied fresh;
try {
fresh = applier.apply(
file.getContent(), sourceName, newHash, ctx.getStorageOpt(), kind);
} catch (final MalFileApplier.ApplyException ae) {
// Engine-internal partial rollback: undo whatever this attempt managed to
// register before the throw. Old appliedMal[key] is untouched — it's still
// serving — so removing the partial set is the only mutation needed.
applier.remove(ae.getPartiallyRegistered(), ctx.getStorageOpt());
throw new EngineCompileException(ae);View on GitHub (pinned to 102af09b4a)
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
Defensive patterns
Strategy: validation
Validate before calling
final boolean malReady = moduleManager.find(CoreModule.NAME) != null
&& getManager().find(CoreModule.NAME).provider().getService(MeterSystem.class) != null;
if (!malReady) deferOrReject("MAL compile needs CoreModule MeterSystem"); Try / catch
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.
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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()
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()
- decorate() not supported for histogram metrics
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/655cef1e318af24c.
Report an issue: GitHub.