apache/skywalking · critical · ModuleStartException

Failed to load LAL config rules

Error message

Failed to load LAL config rules

What it means

Thrown when LALConfigs.load cannot open the configured LAL rules directory: the load loop wraps per-file parse errors as debug logs (tolerated), but a FileNotFoundException for the directory itself propagates as ModuleStartException, failing module start. Individual unreadable/invalid rule files are skipped with a debug log — only the missing catalog directory is fatal.

Source

Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/LALConfigs.java:195

                    final String src = sourceFileName.getOrDefault(ruleName, ruleName + ".yaml");
                    // Resolve each rule's line in the SAME text, so a generated class can name the
                    // location an operator opens. Without this the compiler receives only a file
                    // name and every class is labelled unknown. snakeyaml's bean binding discards
                    // positional marks, hence the second compose pass.
                    final DslYamlLineIndex lineIndex = DslYamlLineIndex.index(
                        new String(bytes, StandardCharsets.UTF_8), "rules");
                    for (int i = 0; i < configs.getRules().size(); i++) {
                        stampSource(configs.getRules().get(i), src);
                        configs.getRules().get(i).setLineNo(lineIndex.rule(i).getEntryLine());
                    }
                    out.add(configs);
                } catch (final IOException ioe) {
                    log.debug("Failed to parse LAL rule {}", ruleName, ioe);
                }
            }
            return out;
        } catch (FileNotFoundException e) {
            throw new ModuleStartException("Failed to load LAL config rules", e);
        }
    }

    /**
     * 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 LALConfigs configs) {
        final List<LayerDefinition> defs = configs.getLayerDefinitions();
        if (defs == null || defs.isEmpty()) {
            return;
        }
        for (final LayerDefinition def : defs) {
            try {
                def.register();
            } catch (RuntimeException e) {

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Verify the lalPath directory exists at runtime (absolute paths are safer than relative in containers)
  2. Fix the path in application.yml under log-analyzer provider config
  3. If deploying a custom dist, ensure the lal/ catalog is included in the package/image
  4. Note: individual malformed rule files only log at DEBUG — enable debug logging to find silently skipped rules

Example fix

# before (application.yml)
log-analyzer:
  selector: default
  default:
    lalPath: /skywalking/lal

# after
log-analyzer:
  selector: default
  default:
    lalPath: /opt/skywalking/config/lal   # directory that actually exists
Defensive patterns

Strategy: validation

Validate before calling

# Pre-start check in the deployment:
#   test -d "$LAL_PATH" || echo "lalPath missing: $LAL_PATH"
# Or in Java before module boot:
// if (!new File(config.getLalPath()).isDirectory()) throw new IllegalStateException("lalPath does not exist: " + config.getLalPath());

Try / catch

try {
    List<LALConfigs> configs = LALConfigs.load(lalPath, lalFiles);
} catch (ModuleStartException e) {
    // FileNotFoundException cause -> fix the path in application.yml, do not retry
}

Prevention

When it happens

Trigger: log-analyzer config lalPath: <dir> pointing at a path that does not exist in the OAP deployment (or not readable); a dist/assembly where the lal/ folder was not copied; a Docker image built without the config catalog.

Common situations: Custom lalPath in application.yml with a typo; running the OAP jar from an unexpected working directory with a relative path; a trimmed container image that dropped the lal/ rules directory.

Related errors


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