{"record":{"id":"de9aed29dbe5798a","repo":"apache/skywalking","slug":"failed-to-load-lal-config-rules","errorCode":null,"errorMessage":"Failed to load LAL config rules","messagePattern":"Failed to load LAL config rules","errorType":"exception","errorClass":"ModuleStartException","httpStatus":null,"severity":"critical","filePath":"oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/LALConfigs.java","lineNumber":195,"sourceCode":"                    final String src = sourceFileName.getOrDefault(ruleName, ruleName + \".yaml\");\n                    // Resolve each rule's line in the SAME text, so a generated class can name the\n                    // location an operator opens. Without this the compiler receives only a file\n                    // name and every class is labelled unknown. snakeyaml's bean binding discards\n                    // positional marks, hence the second compose pass.\n                    final DslYamlLineIndex lineIndex = DslYamlLineIndex.index(\n                        new String(bytes, StandardCharsets.UTF_8), \"rules\");\n                    for (int i = 0; i < configs.getRules().size(); i++) {\n                        stampSource(configs.getRules().get(i), src);\n                        configs.getRules().get(i).setLineNo(lineIndex.rule(i).getEntryLine());\n                    }\n                    out.add(configs);\n                } catch (final IOException ioe) {\n                    log.debug(\"Failed to parse LAL rule {}\", ruleName, ioe);\n                }\n            }\n            return out;\n        } catch (FileNotFoundException e) {\n            throw new ModuleStartException(\"Failed to load LAL config rules\", e);\n        }\n    }\n\n    /**\n     * Funnel any inline {@code layerDefinitions:} entries through {@code Layer.register}.\n     * Conflict checks (reserved-range, name uniqueness, ordinal uniqueness, sealed-state) live\n     * in {@code Layer.register}; failures here surface with the offending rule name in\n     * the stack trace.\n     */\n    private static void registerInlineLayers(final String ruleName, final LALConfigs configs) {\n        final List<LayerDefinition> defs = configs.getLayerDefinitions();\n        if (defs == null || defs.isEmpty()) {\n            return;\n        }\n        for (final LayerDefinition def : defs) {\n            try {\n                def.register();\n            } catch (RuntimeException e) {","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/LALConfigs.java#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the lalPath directory exists at runtime (absolute paths are safer than relative in containers)","Fix the path in application.yml under log-analyzer provider config","If deploying a custom dist, ensure the lal/ catalog is included in the package/image","Note: individual malformed rule files only log at DEBUG — enable debug logging to find silently skipped rules"],"exampleFix":"# before (application.yml)\nlog-analyzer:\n  selector: default\n  default:\n    lalPath: /skywalking/lal\n\n# after\nlog-analyzer:\n  selector: default\n  default:\n    lalPath: /opt/skywalking/config/lal   # directory that actually exists","handlingStrategy":"validation","validationCode":"# Pre-start check in the deployment:\n#   test -d \"$LAL_PATH\" || echo \"lalPath missing: $LAL_PATH\"\n# Or in Java before module boot:\n// if (!new File(config.getLalPath()).isDirectory()) throw new IllegalStateException(\"lalPath does not exist: \" + config.getLalPath());","typeGuard":null,"tryCatchPattern":"try {\n    List<LALConfigs> configs = LALConfigs.load(lalPath, lalFiles);\n} catch (ModuleStartException e) {\n    // FileNotFoundException cause -> fix the path in application.yml, do not retry\n}","preventionTips":["Use absolute lalPath paths in container deployments","Include the lal/ catalog in image build assertions","Remember per-file parse failures are silent DEBUG logs — enable them when rules seem ignored"],"tags":["lal","log-analyzer","config","startup","file-not-found"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}