grpc/grpc-java · error · ResourceInvalidException
${structOrError.getErrorDetail()}
Error message
${structOrError.getErrorDetail()} What it means
While processing a ClusterLoadAssignment, each LocalityLbEndpoints is parsed via parseLocalityLbEndpoints, which returns a StructOrError. If that struct carries an errorDetail (the locality's own validation failed, e.g. missing locality, bad load balancer weight or sockets), processClusterLoadAssignment rethrows it as a ResourceInvalidException, failing the whole EDS resource.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsEndpointResource.java:129
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);
if (structOrError == null) {
continue;
}
if (structOrError.getErrorDetail() != null) {
throw new ResourceInvalidException(structOrError.getErrorDetail());
}
LocalityLbEndpoints localityLbEndpoints = structOrError.getStruct();
int priority = localityLbEndpoints.priority();
maxPriority = Math.max(maxPriority, priority);
// Note endpoints with health status other than HEALTHY and UNKNOWN are still
// handed over to watching parties. It is watching parties' responsibility to
// filter out unhealthy endpoints. See EnvoyProtoData.LbEndpoint#isHealthy().
Locality locality = parseLocality(localityLbEndpointsProto.getLocality());
localityLbEndpointsMap.put(locality, localityLbEndpoints);
if (!priorities.containsKey(priority)) {
priorities.put(priority, new HashSet<>());
}
if (!priorities.get(priority).add(locality)) {
throw new ResourceInvalidException("ClusterLoadAssignment has duplicate locality:"
+ locality + " for priority:" + priority);
}
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Read the errorDetail text — it names the specific locality field that failed validation
- Fix the offending LocalityLbEndpoints in the management server's EDS output
- Ensure each locality has a valid Locality (region/zone/sub_zone) and valid endpoints
- Test EDS payloads with grpc-java xDS interop tests before deploying
Defensive patterns
Strategy: try-catch
Validate before calling
for (LocalityLbEndpoints lle : assignment.getEndpointsList()) {
if (!lle.hasLocality()) throw new IllegalArgumentException("locality missing in EDS payload");
if (lle.getLbEndpointsCount() == 0) throw new IllegalArgumentException("empty locality");
} Try / catch
try {
update = XdsEndpointResource.getInstance().parse(args, resource);
} catch (ResourceInvalidException e) {
logger.warn("EDS rejected: {}", e.getMessage()); // errorDetail names the bad locality field
} Prevention
- Validate each LocalityLbEndpoints (locality present, endpoints valid) before sending
- Fix the field named in errorDetail at the management server
- Run xDS interop tests on EDS payloads
When it happens
Trigger: An EDS ClusterLoadAssignment contains a locality whose LocalityLbEndpoints fails per-locality validation — e.g. missing locality field, invalid endpoint address/port, or bad lb_endpoints entries — surfacing the inner error message.
Common situations: Control plane generating malformed endpoints for a locality; partially-populated LocalityLbEndpoints from service discovery backends; hand-written EDS test fixtures with missing fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid message type: ${unpackedMessage.getClass()}
- Failed to parse channel credentials: " + e.getMessage()
- ClusterLoadAssignment has duplicate locality:${locality} for
- ClusterLoadAssignment has sparse priorities
- Unknown denominator type of ${percent}
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/641c425005f8acbf.
Report an issue: GitHub.