grpc/grpc-java · error · ResourceInvalidException
Invalid message type: ${unpackedMessage.getClass()}
Error message
Invalid message type: ${unpackedMessage.getClass()} What it means
The LDS (Listener) resource parser doParse expects the Any in a Listener resource to unpack to envoy.config.listener.v3.Listener. If the unpacked message is any other type, the resource is rejected with 'Invalid message type: <class>'. This guards against a management server serving the wrong resource under the Listener type URL.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:106
public String typeUrl() {
return ADS_TYPE_URL_LDS;
}
@Override
public boolean shouldRetrieveResourceKeysForArgs() {
return false;
}
@Override
protected boolean isFullStateOfTheWorld() {
return true;
}
@Override
protected LdsUpdate doParse(Args args, Message unpackedMessage)
throws ResourceInvalidException {
if (!(unpackedMessage instanceof Listener)) {
throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass());
}
Listener listener = (Listener) unpackedMessage;
if (listener.hasApiListener()) {
return processClientSideListener(listener, args);
} else {
return processServerSideListener(listener, args);
}
}
private LdsUpdate processClientSideListener(Listener listener, XdsResourceType.Args args)
throws ResourceInvalidException {
// Unpack HttpConnectionManager from the Listener.
HttpConnectionManager hcm;
try {
hcm = unpackCompatibleType(
listener.getApiListener().getApiListener(), HttpConnectionManager.class,
TYPE_URL_HTTP_CONNECTION_MANAGER, null);View on GitHub (pinned to 64daddc1f3)
Solutions
- Verify the management server sends envoy.config.listener.v3.Listener messages for LDS resources
- Check that each Any's type_url corresponds to the Listener resource type
- Fix ADS routing so Listener resources are not delivered under another type's subscription
- Compare control plane and client xDS versions (v2 vs v3 type URLs) and align them
Example fix
// before (wrong message under LDS type_url)
resources { any { type_url: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration" ... } }
// after
resources { any { type_url: "type.googleapis.com/envoy.config.listener.v3.Listener" ... } } Defensive patterns
Strategy: validation
Validate before calling
// Control-plane side: assert LDS payloads are Listener messages
for (com.google.protobuf.Any any : discoveryResponse.getResourcesList()) {
try {
if (!(any.unpack(io.envoyproxy.envoy.config.listener.v3.Listener.class)
instanceof io.envoyproxy.envoy.config.listener.v3.Listener)) {
throw new IllegalStateException("Non-Listener resource in LDS response");
}
} catch (InvalidProtocolBufferException e) {
throw new IllegalStateException("Bad LDS resource: " + any.getTypeUrl(), e);
}
} Type guard
boolean isListenerResource(com.google.protobuf.Any any) {
try {
return any.is(io.envoyproxy.envoy.config.listener.v3.Listener.class);
} catch (InvalidProtocolBufferException e) {
return false;
}
} Try / catch
// Client side: detect wrong-type LDS payloads from watcher errors
@Override public void onError(Status error) {
if (error.getDescription().startsWith("Invalid message type:")) {
logger.log(WARNING, "LDS response carried wrong message type: " + error.getDescription());
}
} Prevention
- Verify management-server resource-to-type-URL mapping for LDS
- Use Any.pack(listener) rather than hand-built Any messages
- Check ADS routing so Listener subscriptions only receive Listener resources
- Align v2/v3 xDS type URLs across control plane and client
When it happens
Trigger: An xDS response for the ListenerService/LdsResource type URL contains a message that is not a Listener (e.g. a RouteConfiguration or Cluster packed under the LDS type URL, or a v2 Listener with mismatched type_url mapping); doParse's instanceof check fails.
Common situations: Misconfigured management server mapping resource names to the wrong types; ADS multiplexing sending resources to the wrong stream type; custom servers hand-building DiscoveryResponses with wrong Any contents; v2/v3 type-URL skew.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not parse HttpConnectionManager config from ApiListene
- Invalid message type: ${unpackedMessage.getClass()}
- Failed to parse metadata key: %s, type: %s. Error: %s
- Unknown permission rule case: " + permission.getRuleCase()
- Unknown principal identifier case: " + principal.getIdentifi
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/3811c927403d5d98.
Report an issue: GitHub.