apache/skywalking · critical · IllegalStateException
LALSourceTypeProvider {} for layer {} declared inputType {}
Error message
LALSourceTypeProvider {} for layer {} declared inputType {} — LAL accepts only LogData / LogData.Builder (default agent path), a protobuf Message subclass, or a type implementing {}. Update the provider's inputType() or implement ToJson on {}. What it means
Thrown when validating a LALSourceTypeProvider SPI implementation whose inputType() returns a class outside the accepted contract: LogData/LogData.Builder, a protobuf Message/Message.Builder, or anything implementing ToJson. The check exists because the codegen must know how to surface the input to the rule — typed getter access for protos, JSON conversion via ToJson, or the LogData path. It is an IllegalStateException during provider/rule wiring.
Source
Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/LogFilterListener.java:474
* (custom POJO inputs). A provider that declares an out-of-family
* {@code inputType()} will fail downstream dispatch (the framework
* fallback {@code (LogData.Builder)} cast throws ClassCastException at
* runtime), so we surface the contract violation here at startup with a
* pointer at the SPI rather than letting it leak into the receiver hot path.
*/
private static void validateInputTypeContract(final LALSourceTypeProvider provider) {
final Class<?> inputType = provider.inputType();
if (inputType == null) {
return;
}
if (LogData.class.isAssignableFrom(inputType)
|| LogData.Builder.class.isAssignableFrom(inputType)
|| Message.class.isAssignableFrom(inputType)
|| Message.Builder.class.isAssignableFrom(inputType)
|| ToJson.class.isAssignableFrom(inputType)) {
return;
}
throw new IllegalStateException(
"LALSourceTypeProvider " + provider.getClass().getName() + " for layer "
+ provider.layer() + " declared inputType " + inputType.getName()
+ " — LAL accepts only LogData / LogData.Builder (default agent path), "
+ "a protobuf Message subclass, or a type implementing "
+ ToJson.class.getName() + ". Update the provider's inputType() or "
+ "implement ToJson on " + inputType.getName() + ".");
}
private static Class<?> resolveInputType(final LALConfig config,
final LALSourceTypeProvider spiProvider) throws ModuleStartException {
final String yamlType = config.getInputType();
if (yamlType != null && !yamlType.isEmpty()) {
try {
return Class.forName(yamlType);
} catch (ClassNotFoundException e) {
throw new ModuleStartException(
"LAL rule '" + config.getName() + "' declares inputType '"
+ yamlType + "' but the class was not found.", e);View on GitHub (pinned to 102af09b4a)
Solutions
- Implement ToJson on your input class (simplest for POJOs — LAL converts it to a parsed map)
- Or make the input a protobuf Message and return that from inputType()
- Or return null from inputType() to fall back to the LogMetadata default path
- Register the corrected provider in META-INF/services and rebuild
Example fix
// before
public class MyProvider implements LALSourceTypeProvider {
public Class<?> inputType() { return MyPojo.class; }
}
// after
public class MyPojo implements ToJson { ... }
public class MyProvider implements LALSourceTypeProvider {
public Class<?> inputType() { return MyPojo.class; }
} Defensive patterns
Strategy: type-guard
Validate before calling
// SPI self-check a provider can run in tests:
Class<?> t = provider.inputType();
boolean ok = t == null
|| LogData.class.isAssignableFrom(t)
|| LogData.Builder.class.isAssignableFrom(t)
|| com.google.protobuf.Message.class.isAssignableFrom(t)
|| com.google.protobuf.Message.Builder.class.isAssignableFrom(t)
|| ToJson.class.isAssignableFrom(t);
if (!ok) throw new IllegalStateException("inputType contract violated: " + t); Type guard
boolean isValidLalInputType(Class<?> t) {
return t == null
|| LogData.class.isAssignableFrom(t)
|| LogData.Builder.class.isAssignableFrom(t)
|| Message.class.isAssignableFrom(t)
|| Message.Builder.class.isAssignableFrom(t)
|| ToJson.class.isAssignableFrom(t);
} Prevention
- Default to implementing ToJson on custom POJO inputs
- Add a unit test that calls the same contract check for your provider
- Return null from inputType() when the LogMetadata fallback is intended
When it happens
Trigger: A receiver plugin implements LALSourceTypeProvider and returns a plain POJO class from inputType() that is neither a protobuf Message nor ToJson; returning a collection/Map/record type; generics erased types.
Common situations: Writing a custom log receiver and its LAL source provider; porting a v1 provider that had no type contract; returning a DTO class and forgetting the ToJson adapter.
Related errors
- LAL rule '{}' declares inputType '{}' but the class was not
- LAL rule '{}' declares outputType '{}' but neither a registe
- tag() reads LogData tags but the input type is {inputTypeNam
- sourceAttribute() requires exactly one string literal argume
- Cannot resolve {desc} — no matching codegen path. Parser typ
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/6e1e9a3016fafdb8.
Report an issue: GitHub.