apache/skywalking · critical · ModuleStartException
Layer {} has already set {} rule.
Error message
Layer {} has already set {} rule. What it means
Thrown during static rule load when two rules targeting the SAME Layer share the same name: per-layer DSL maps (initDsls keyed by Layer) reject the second registration of an identical name. This is the layer-scoped twin of the auto-layer duplicate-name error — the same name in two different layers is fine, but not twice within one layer.
Source
Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/LogFilterListener.java:258
*/
public void loadStaticRules() throws Exception {
final Map<Layer, Map<String, DSL>> initDsls = new HashMap<>();
final Map<String, DSL> initAutoDsls = new HashMap<>();
final List<LALConfig> configList = LALConfigs.load(analyzerConfig.getLalPath(), analyzerConfig.lalFiles())
.stream()
.flatMap(it -> it.getRules().stream())
.collect(Collectors.toList());
for (final LALConfig c : configList) {
final CompiledLAL compiled = compile(c);
if (compiled.layer == null) {
if (initAutoDsls.put(c.getName(), compiled.dsl) != null) {
throw new ModuleStartException(
"Auto-layer rules have duplicate name: " + c.getName());
}
} else {
final Map<String, DSL> layerDsls = initDsls.computeIfAbsent(compiled.layer, k -> new HashMap<>());
if (layerDsls.put(c.getName(), compiled.dsl) != null) {
throw new ModuleStartException(
"Layer " + compiled.layer.name() + " has already set " + c.getName() + " rule.");
}
}
// Publish per-rule debug holder into the dsl-debugging registry. sourceName, not
// sourcePath: both routes derive it through LALConfigs.stampSource, so a
// runtime-rule replace puts over the static binding without orphaning it.
LalStaticBindingHook.publish(c.getSourceName(), c.getName(), compiled.dsl.getExpression());
}
// Publish: readers from now on see the startup-complete registry.
this.dsls = initDsls;
this.autoDsls = initAutoDsls;
}
/**
* Compile a single LALConfig into a runnable {@link DSL}. Used by both the startup
* constructor and the runtime-rule hot-update path (LalFileApplier).
*/
public CompiledLAL compile(final LALConfig c) throws ModuleStartException {View on GitHub (pinned to 102af09b4a)
Solutions
- Rename the duplicate rule within that layer
- If the rules genuinely target different layers, verify both layer: declarations resolve to distinct Layer values
- Delete the stale copy if the file was duplicated wholesale
Example fix
# before: two entries with layer: MESH named 'envoy-als' # after: rename the second ruleName: envoy-als-custom
Defensive patterns
Strategy: validation
Validate before calling
# Detect duplicate names within a layer:
# awk '/^layer:/{L=$2} /^ruleName:/{print L, $2}' lal/*.yaml | sort | uniq -d Prevention
- Namespacing convention: prefix rule names with the layer or source
- When copying a shipped per-layer rule, rename immediately
- Review duplicates per layer, not just globally
When it happens
Trigger: Two rules both declaring layer: MESH (or resolved to the same layer) with identical ruleName; copy-pasting an envoy-als style rule and keeping the name; a layerDefinitions inline entry plus an explicit layer: that resolve to the same Layer object.
Common situations: Extending a shipped per-layer rule file (envoy-als.yaml etc.) by duplicating an entry and editing only the body; merging contributed rule files for the same layer.
Related errors
- Auto-layer rules have duplicate name: {name}
- LAL rule {ruleName} layerDefinitions entry rejected: {def}
- Failed to load static LAL rules.
- Failed to compile LAL expression: {dsl}
- Failed to load LAL config rules
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/cad2f9a9873e8b25.
Report an issue: GitHub.