apache/skywalking · error · ApplyException

LAL YAML parsed to empty/malformed — no rules list in {sourc

Error message

LAL YAML parsed to empty/malformed — no rules list in {sourceName}

What it means

ApplyException thrown by LalFileApplier.parse when snakeyaml loads the content but the result is null, has no 'rules' key, or rules is empty — i.e. the YAML is syntactically loadable but not a valid LAL document. Cause is null and the partial list is empty because nothing was applied. Note this fires before per-rule line indexing (DslYamlLineIndex), so it also guards against documents whose top-level structure is a list or a string instead of the expected mapping with 'rules:'

Source

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

                            + "skipping from teardown enumeration", c.getName(), c.getLayer(), sourceName);
                        continue;
                    }
                }
                out.add(new RegisteredRule(layer, c.getName()));
            }
            return Collections.unmodifiableList(out);
        } catch (final Throwable t) {
            log.warn("runtime-rule: failed to parse static LAL content for {} — no rule keys "
                + "enumerated for teardown", sourceName, t);
            return Collections.emptyList();
        }
    }

    private LALConfigs parse(final String yamlContent, final String sourceName) throws ApplyException {
        try (StringReader reader = new StringReader(yamlContent)) {
            final LALConfigs configs = new Yaml().loadAs(reader, LALConfigs.class);
            if (configs == null || configs.getRules() == null || configs.getRules().isEmpty()) {
                throw new ApplyException(
                    "LAL YAML parsed to empty/malformed — no rules list in " + sourceName,
                    null, Collections.emptyList());
            }
            // Resolve each rule's line from the SAME text, exactly as the boot loader does.
            // Without this a hot-updated rule compiles to an unlabelled class while its
            // disk-loaded twin is labelled — the two routes must agree.
            final DslYamlLineIndex lineIndex = DslYamlLineIndex.index(yamlContent, "rules");
            for (int i = 0; i < configs.getRules().size(); i++) {
                configs.getRules().get(i).setLineNo(lineIndex.rule(i).getEntryLine());
            }
            // layerDefinitions: are now permitted in runtime LAL rules; the apply path
            // funnels them through the runtime-layer registry. The rejection that used to
            // live here was removed when runtime dynamic layers became a first-class feature.
            return configs;
        } catch (final ApplyException e) {
            throw e;
        } catch (final Throwable t) {
            throw new ApplyException("LAL YAML parse failure for " + sourceName, t,

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Ensure the document has a non-empty top-level 'rules:' list with at least one rule entry
  2. Verify with a quick local check: loadAs must yield configs != null && configs.getRules() != null && !isEmpty
  3. If you intended a layer-only update, use the layer-definition API path instead of an LAL file apply
  4. Check that template rendering didn't strip the rules section (empty variables)

Example fix

# before
layerDefinitions:
  - name: my-layer
# after (an LAL file must carry rules)
layerDefinitions:
  - name: my-layer
rules:
  - name: first-rule
    layer: my-layer
    exp: "true"
Defensive patterns

Strategy: validation

Validate before calling

try (StringReader r = new StringReader(content)) {
    LALConfigs c = new Yaml().loadAs(r, LALConfigs.class);
    if (c == null || c.getRules() == null || c.getRules().isEmpty()) reject("empty rules list");
}

Try / catch

catch (ApplyException e) when 'parsed to empty/malformed': reject at the upload boundary — this is pure input validation, never retry the same content.

Prevention

When it happens

Trigger: Submitting runtime LAL content such as 'rules:' with nothing under it, a YAML doc whose top key is 'defaultFG'/'layerDefinitions' only, an empty file, or a YAML mapping that deserializes into LALConfigs with a null rules field (e.g. rules spelled 'Rules').

Common situations: Deploying a file with only layerDefinitions and forgetting the rules block; Env-substitution pipeline producing an effectively empty body; Rules list commented out during debugging and shipped anyway; Key casing drift ('Rules:' vs 'rules:') from schema changes in tooling

Understand the failure class

Related errors


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