apache/skywalking · critical · ModuleStartException

Auto-layer rules have duplicate name: {name}

Error message

Auto-layer rules have duplicate name: {name}

What it means

Thrown during static rule load when two rules without an explicit layer (i.e. layer: auto rules) share the same name: loadStaticRules puts compiled DSLs into a name-keyed map (initAutoDsls) and a non-null previous value means a duplicate. Auto-layer rules are stored flat by name because they are selected by absence of service layer, not by a Layer key, making name uniqueness mandatory.

Source

Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/LogFilterListener.java:252

         * {@code RecordSinkListener.Factory.<init>}, which calls {@code moduleManager.find()}
         * and asserts the manager is past prepare.
         *
         * <p>Idempotent against re-entry within the same boot (the Factory only stays in
         * its empty post-construct state until this fires once); calling it twice on the
         * same instance is a programming error.
         */
        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;
        }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Rename one of the two rules so every auto-layer rule name is unique
  2. If the rule belongs to a specific layer, add the layer: declaration — per-layer namespaces are separate
  3. Remove the duplicate file from lalFiles if it was left in by accident

Example fix

# before: default.yaml and my-rules.yaml both contain
ruleName: default

# after: my-rules.yaml
ruleName: my-custom-default
Defensive patterns

Strategy: validation

Validate before calling

# Detect duplicate auto-layer rule names before deploy:
#   grep -h '^ruleName:' lal/*.yaml | sort | uniq -d   # any output = future failure (layer-less rules)

Prevention

When it happens

Trigger: Two LAL YAML files (or two entries in one file) both defining a rule named e.g. 'default' without a layer: declaration; copying a shipped rule file and keeping the name; a rule that omits layer: accidentally (omission means auto).

Common situations: Adding a custom rule file alongside default.yaml and reusing the name 'default'; merging rule sets from two teams; forgetting that omitting layer: puts the rule in the auto bucket.

Related errors


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