apache/skywalking · error · ApplyException

MAL compile failed for {sourceName}

Error message

MAL compile failed for {sourceName}

What it means

ApplyException thrown by MalFileApplier.apply for any phase-1 failure — content parsing/compilation or any pre-register throw that is not PartialRegistrationException. Because the failure happened before MeterSystem registration, the rollback set is deliberately EMPTY: passing a non-empty set would make the caller unregister metrics the still-installed old bundle owns. Layer-registry claims are rolled back first so a failed compile leaks no layer state.

Source

Thrown at oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/apply/MalFileApplier.java:172

            convert = new MetricConvert(rule, meterSystem, pool, ruleLoader, storageOpt);
        } catch (final MetricConvert.PartialRegistrationException pre) {
            // Phase-2 register threw partway. Carry ONLY the subset that actually landed in
            // MeterSystem — the caller uses this set for rollback. Passing the full enumerated
            // set here would remove metrics the old bundle still owns (disastrous on
            // FILTER_ONLY edits, where by definition every metric name is also in the old
            // bundle). The layer-registry changes are reverted now so a failed MeterSystem
            // register does not leak a half-applied layer state.
            layerRegistry.rollback(appliedClaims);
            throw new ApplyException(
                "MAL register failed for " + sourceName + " (partial)",
                pre.getCause() == null ? pre : pre.getCause(),
                pre.getRegisteredBeforeFailure());
        } catch (final Throwable t) {
            // Phase-1 compile failure or other pre-register throw. Nothing was registered with
            // MeterSystem, so rollback set is empty — passing a non-empty set would cause the
            // caller to unregister metrics the old bundle owns and this apply never touched.
            layerRegistry.rollback(appliedClaims);
            throw new ApplyException("MAL compile failed for " + sourceName, t, Collections.emptySet());
        }
        // All DDL for this file's metrics is now fired. If the opt deferred its schema fence
        // (batched apply via withSchemaChangeDeferredFence), run the single barrier here so the
        // whole file waits ONCE instead of one fence per metric/downsampling. A fence timeout is
        // a non-fatal WARN inside the closure; only a barrier transport error throws, which
        // aborts this apply exactly as an inline per-resource fence would have.
        //
        // EXCEPTION: when fenceRunByCaller is set (the runtime-rule REST apply), the orchestrator
        // runs the fence itself AFTER the durable commit + peer resume, on a background thread, so
        // a long (3-min) cluster-propagation wait neither blocks the apply nor holds peers
        // suspended. We only fire the DDL here and leave the closure for the caller to run.
        if (!storageOpt.isFenceRunByCaller()) {
            try {
                storageOpt.runDeferredFence();
            } catch (final StorageException e) {
                layerRegistry.rollback(appliedClaims);
                throw new ApplyException("schema fence failed for " + sourceName, e, metricNames);
            }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Inspect the cause for the exact compile/parse failure and fix the expression or schema
  2. Pre-validate with the same parse path: Yaml().loadAs(reader, Rule.class) must yield a rule with metricPrefix and metricsRules
  3. Align the MAL grammar version you author against the running OAP version (check the MAL docs for supported functions)
  4. Re-apply once fixed; no cleanup is needed because nothing was registered (empty rollback set)

Example fix

# before
exp: increase(total{inventory.recode_type='pod'},5m).scale(0.016666  # typo/truncation
# after
exp: "increase(total{inventory.recode_type='pod'},5m).scale(0.016666)"
Defensive patterns

Strategy: try-catch

Validate before calling

try (StringReader r = new StringReader(content)) {
    Rule rule = new Yaml().loadAs(r, Rule.class);
    if (rule == null || rule.getMetricPrefix() == null || rule.getMetricsRules() == null) reject("incomplete MAL doc");
}

Try / catch

catch (ApplyException e) when 'MAL compile failed': rollback set is empty by contract — do NOT unregister anything; fix the compile error from e.getCause() and re-apply fresh.

Prevention

When it happens

Trigger: Applying MAL content that fails YAML parse or expression compile: bad exp syntax, missing metricPrefix, unknown MAL function, or metric rule names that fail validation — anything thrown by new MetricConvert(...) before any metric lands in MeterSystem.

Common situations: Invalid expression grammar after editing exp fields; Version skew: MAL functions added in a newer OAP used against an older server; Files missing required top-level keys (metricPrefix) so compile aborts immediately

Related errors


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