grpc/grpc-java · error · ResourceInvalidException
Invalid message type: ${unpackedMessage.getClass()}
Error message
Invalid message type: ${unpackedMessage.getClass()} What it means
XdsEndpointResource.doParse expects the unpacked Any payload of an EDS (EndpointDiscoveryResponse) resource to be a ClusterLoadAssignment protobuf. If the Any contains some other message type, the parser throws ResourceInvalidException naming the unexpected class.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsEndpointResource.java:106
@Override
public boolean shouldRetrieveResourceKeysForArgs() {
return true;
}
@Override
protected boolean isFullStateOfTheWorld() {
return false;
}
@Override
protected Class<ClusterLoadAssignment> unpackedClassName() {
return ClusterLoadAssignment.class;
}
@Override
protected EdsUpdate doParse(Args args, Message unpackedMessage) throws ResourceInvalidException {
if (!(unpackedMessage instanceof ClusterLoadAssignment)) {
throw new ResourceInvalidException("Invalid message type: " + unpackedMessage.getClass());
}
return processClusterLoadAssignment((ClusterLoadAssignment) unpackedMessage);
}
private static boolean isEnabledXdsDualStack() {
return GrpcUtil.getFlag(GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS, false);
}
private static EdsUpdate processClusterLoadAssignment(ClusterLoadAssignment assignment)
throws ResourceInvalidException {
Map<Integer, Set<Locality>> priorities = new HashMap<>();
Map<Locality, LocalityLbEndpoints> localityLbEndpointsMap = new LinkedHashMap<>();
List<Endpoints.DropOverload> dropOverloads = new ArrayList<>();
int maxPriority = -1;
for (io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints localityLbEndpointsProto
: assignment.getEndpointsList()) {
StructOrError<LocalityLbEndpoints> structOrError =
parseLocalityLbEndpoints(localityLbEndpointsProto);View on GitHub (pinned to 64daddc1f3)
Solutions
- Fix the management server to send ClusterLoadAssignment for EDS type URLs
- Verify the resource's Any type_url matches io.grpc.xds EDS expectations
- Capture the raw xDS response (grpc-xds debug logs) to inspect the actual payload
- Update protobuf/xDS version alignment between control plane and grpc-java
Defensive patterns
Strategy: try-catch
Validate before calling
if (!resource.getMessage().is(ClusterLoadAssignment.class)) {
throw new IllegalArgumentException("EDS resource is not ClusterLoadAssignment");
} Type guard
static boolean isClusterLoadAssignment(Any any) {
return any.is(ClusterLoadAssignment.class);
} Try / catch
try {
update = XdsEndpointResource.getInstance().parse(args, resource);
} catch (ResourceInvalidException e) {
logger.warn("Bad EDS payload: {}", e.getMessage());
} Prevention
- Ensure the management server sends ClusterLoadAssignment under EDS type URLs
- Log raw Any type_url on parse failures for diagnosis
- Keep proto registries aligned between control plane and grpc-java
When it happens
Trigger: An EDS response resource whose type_url resolves (via the registered type registry/unpack) to a message that is not ClusterLoadAssignment — e.g. a misconfigured control plane sending the wrong resource body under an EDS type URL.
Common situations: Misbehaving or buggy xDS management server; custom control planes emitting wrong payloads; type-URL/registry mismatches after protobuf upgrades.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- ${structOrError.getErrorDetail()}
- Failed to parse channel credentials: " + e.getMessage()
- Failed to parse access token credentials: " + e.getMessage()
- ClusterLoadAssignment has duplicate locality:${locality} for
- ClusterLoadAssignment has sparse priorities
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/c8ebae19a6f303b6.
Report an issue: GitHub.