apache/skywalking · error · UnexpectedException
MAL rule {} layerDefinitions entry rejected: {}
Error message
MAL rule {} layerDefinitions entry rejected: {} What it means
UnexpectedException thrown when an inline 'layerDefinitions:' entry in a MAL rule is rejected by Layer.register — the central gatekeeper for layer registration. register() enforces reserved ordinal ranges, name uniqueness, ordinal uniqueness, and the sealed state of the layer registry; any RuntimeException from it is re-thrown with the offending rule name and the layer definition string.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/prometheus/rule/Rules.java:187
}
}
/**
* Funnel any inline {@code layerDefinitions:} entries through {@code Layer.register}.
* Conflict checks (reserved-range, name uniqueness, ordinal uniqueness, sealed-state) live
* in {@code Layer.register}; failures here surface with the offending rule name in
* the stack trace.
*/
private static void registerInlineLayers(final String ruleName, final Rule rule) {
final List<LayerDefinition> defs = rule.getLayerDefinitions();
if (defs == null || defs.isEmpty()) {
return;
}
for (final LayerDefinition def : defs) {
try {
def.register();
} catch (RuntimeException e) {
throw new UnexpectedException(
"MAL rule " + ruleName + " layerDefinitions entry rejected: " + def, e);
}
}
}
}
View on GitHub (pinned to 102af09b4a)
Solutions
- Read the wrapped cause from Layer.register — it states the exact conflict (duplicate name, duplicate ordinal, reserved range, or sealed registry)
- Change the layer name and/or ordinal in the rule's layerDefinitions so they are globally unique and outside reserved ranges
- If a layer with that name is already registered (e.g. created via UI), remove the inline definition and reference the existing layer instead
- If the registry is sealed, move the layerDefinition to a rule that loads before sealing, or register the layer through the supported config path
Example fix
# before
layerDefinitions:
- name: custom-layer
value: 9000 # reserved range collision
# after
layerDefinitions:
- name: custom-layer
value: 7000 Defensive patterns
Strategy: validation
Validate before calling
// Before registering: check uniqueness against the Layer registry you target
Optional<Layer> clashName = Layer.ALL.values().stream().filter(l -> l.name().equals(def.getName())).findAny();
Optional<Layer> clashOrdinal = Layer.ALL.values().stream().filter(l -> l.ordinal() == def.getValue()).findAny();
if (clashName.isPresent() || clashOrdinal.isPresent()) throw new IllegalStateException("layer conflict"); Try / catch
catch (UnexpectedException e) { /* message names the rule + def; cause says which Layer.register rule failed */ } Prevention
- Keep a single authoritative table of custom layer names/ordinals across all rules
- Avoid reserved ordinal ranges documented for built-in layers
- Don't define layers inline in more than one rule
When it happens
Trigger: A rule YAML declares layerDefinitions whose 'name' already exists, whose 'value' (ordinal) collides with an existing layer, or whose ordinal falls inside a reserved range; also when the layer registry has been sealed (rules load after boot-time sealing) so no new registrations are accepted. The full definition and cause are in the exception chain.
Common situations: Two custom rules both defining a layer with the same name or ordinal; copying a rule file and editing the layer name but not the ordinal; defining a layer in the 9000+ (or otherwise reserved) ordinal range; layer conflicts between an inline definition and layers registered from the UI/API layer endpoint.
Related errors
- Load rule file {} failed
- Some configuration files of enabled rules are not found, ena
- Load rule {} failed
- Load meter analyzer configs failed
- Failed to compile hierarchy rule: {name}, expression: {expre
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/bdc0d54a131e9585.
Report an issue: GitHub.