apache/skywalking · critical · ModuleStartException

LAL rule '{}' declares outputType '{}' but neither a registe

Error message

LAL rule '{}' declares outputType '{}' but neither a registered LALOutputBuilder name nor a class was found.

What it means

Thrown when a LAL rule's outputType: value cannot be resolved: if it contains no dot it is first treated as a registered LALOutputBuilder short name (discovered via ServiceLoader); otherwise/afterwards it is tried as an FQCN via Class.forName(). When both fail — unknown short name and unloadable class — compilation aborts. outputType selects the AbstractLog subclass the rule's sink builds.

Source

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

        private static Class<?> resolveOutputType(
                final LALConfig config,
                final LALSourceTypeProvider spiProvider) throws ModuleStartException {
            // Per-rule YAML config takes priority
            final String yamlType = config.getOutputType();
            if (yamlType != null && !yamlType.isEmpty()) {
                // Try short name first (no '.' means it's not a FQCN)
                if (!yamlType.contains(".")) {
                    final Class<?> byName = loadOutputBuilderNames().get(yamlType);
                    if (byName != null) {
                        return byName;
                    }
                }
                // Fall back to FQCN
                try {
                    return Class.forName(yamlType);
                } catch (ClassNotFoundException e) {
                    throw new ModuleStartException(
                        "LAL rule '" + config.getName() + "' declares outputType '"
                            + yamlType + "' but neither a registered LALOutputBuilder name"
                            + " nor a class was found.", e);
                }
            }
            // Fall back to SPI default for the layer
            if (spiProvider != null) {
                final Class<?> spiOutput = spiProvider.outputType();
                if (spiOutput != null) {
                    return spiOutput;
                }
            }
            return null; // DSL.of() will default to Log.class
        }

        @Override
        public LogAnalysisListener create(Layer layer) {
            // Snapshot the suspended set once so a concurrent suspend/resume can't flip behaviour

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Use the exact registered short name of an LALOutputBuilder SPI implementation (check META-INF/services entries)
  2. Or use the fully-qualified class name of an AbstractLog subclass that is on the classpath
  3. Ship the jar containing the output class/builder into oap-libs
  4. Omit outputType to use the layer's SPI default or the built-in Log output

Example fix

# before
outputType: mylog

# after (either form)
outputType: com.mycompany.log.MyLogOutput
Defensive patterns

Strategy: validation

Validate before calling

// Pre-deploy outputType resolution mirror:
Class<?> resolve(String v, Map<String, Class<?>> spiNames) throws Exception {
    if (!v.contains(".")) {
        Class<?> c = spiNames.get(v);
        if (c != null) return c;
    }
    return Class.forName(v); // throws -> rule would fail at boot
}

Try / catch

try {
    Class<?> out = resolveOutputType(config, spiProvider);
} catch (ModuleStartException e) {
    // fix the short name (must match an LALOutputBuilder registration) or use a valid FQCN
}

Prevention

When it happens

Trigger: outputType: my-log with no LALOutputBuilder SPI registered under that short name and no class named my-log; an FQCN whose jar is not on the classpath; casing/typo in either form.

Common situations: Writing a custom output entity but forgetting the META-INF/services registration for the builder; deploying the rule without the custom output jar; renaming the output class without updating rules.

Related errors


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