apache/skywalking · error · MetricConvert.PartialRegistrationException

phase-2 register failed for {}

Error message

phase-2 register failed for {}

What it means

Thrown by MetricConvert.apply (phase 2) when an individual Analyzer's register() call fails during a MAL rule application — e.g. a metric name colliding with an existing registration or a meter-system rejection. It is a PartialRegistrationException carrying the accurate set of metric names that DID register before the failure, so the caller can roll back exactly those and leave the previously active bundle intact (critical for FILTER_ONLY or partial edits where blindly unregistering the full enumerated list would wipe untouched metrics).

Source

Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/MetricConvert.java:185

                    putIfNonEmpty(meta, "exp", r.getExp());
                    putIfNonEmpty(meta, "expSuffix", rule.getExpSuffix());
                    putIfNonEmpty(meta, "expPrefix", rule.getExpPrefix());
                    holder.setMetadata(meta);
                }
                return analyzer;
            }
        ).collect(toList());
        // Phase 2 — register. Track each metric name as it's successfully registered so a
        // mid-phase throw gives the caller an accurate "actually registered" set. The previous
        // design left the caller using the full enumerated metric list for rollback, which was
        // catastrophic for FILTER_ONLY edits: a compile surprise between register() calls would
        // wipe the old bundle's metrics that this apply attempt never touched.
        final Set<String> registered = new LinkedHashSet<>(prepared.size());
        for (final Analyzer a : prepared) {
            try {
                a.register();
            } catch (final Throwable t) {
                throw new PartialRegistrationException(
                    "phase-2 register failed for " + a.getMetricName(),
                    t, Collections.unmodifiableSet(new LinkedHashSet<>(registered)));
            }
            registered.add(a.getMetricName());
        }
        this.analyzers = prepared;
        this.registeredMetricNames = Collections.unmodifiableSet(registered);
    }

    /**
     * Metric names that completed phase-2 register on this instance — the set the caller would
     * unregister to undo a successful apply. Same as {@code analyzers.stream().map(getMetricName)}
     * for a fully-constructed instance; the field exists so {@link PartialRegistrationException}
     * can carry the same value for the partial case.
     */
    @Getter
    private final Set<String> registeredMetricNames;

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Read the message for the failing metric name and the cause for why register() rejected it
  2. Fix the rule (rename the colliding metric, keep the metric type consistent with the existing registration)
  3. On failure, unregister exactly the names in the exception's registered set — do NOT unregister the full rule's metric list
  4. After fixing, re-apply the rule; the old bundle remains active until a clean apply succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

// Before apply, check every metric name is free or owned by this rule:
// for (String name : ruleMetricNames) {
//     MeterSystem existing = ...; if (registeredElsewhere(name)) reject early;
// }

Try / catch

try {
    convert.apply(...);
} catch (PartialRegistrationException e) {
    // roll back ONLY e.getRegisteredMetricNames() (the accurate partial set),
    // never the full enumerated metric list; the previous bundle stays active
    for (String name : e.getRegisteredMetricNames()) {
        meterSystem.unregister(name); // or your registry's removal API
    }
    // surface the failing metric name from e.getMessage() to the rule author
}

Prevention

When it happens

Trigger: A runtime MAL rule update (dynamic configuration / runtime-rule channel) where one metric in the rule fails register() — duplicate metric name across rules, incompatible metric type vs an existing metric, or analyzer validation errors; also at startup apply of log-mal-rules.

Common situations: Two meter rules both declaring metric 'x'; changing a metric's type (e.g. histogram → counter) while the old one is still registered; a live rule edit rejected mid-bundle.

Related errors


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