grpc/grpc-java · error · ResourceInvalidException
structOrError.getErrorDetail()
Error message
structOrError.getErrorDetail()
What it means
After resolving the cluster's type-specific parsing, processCluster re-throws any error detail stored in the resulting StructOrError as a ResourceInvalidException. This propagates an error that occurred inside a nested parser (e.g. parseEdsCluster, parseAggregateCluster) up to the CDS resource parse layer.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:160
ServerInfo serverInfo,
LoadBalancerRegistry loadBalancerRegistry)
throws ResourceInvalidException {
StructOrError<CdsUpdate.Builder> structOrError;
switch (cluster.getClusterDiscoveryTypeCase()) {
case TYPE:
structOrError = parseNonAggregateCluster(cluster,
certProviderInstances, serverInfo);
break;
case CLUSTER_TYPE:
structOrError = parseAggregateCluster(cluster);
break;
case CLUSTERDISCOVERYTYPE_NOT_SET:
default:
throw new ResourceInvalidException(
"Cluster " + cluster.getName() + ": unspecified cluster discovery type");
}
if (structOrError.getErrorDetail() != null) {
throw new ResourceInvalidException(structOrError.getErrorDetail());
}
CdsUpdate.Builder updateBuilder = structOrError.getStruct();
ImmutableMap<String, ?> lbPolicyConfig = LoadBalancerConfigFactory.newConfig(cluster,
enableLeastRequest);
NameResolver.ConfigOrError configOrError
= GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);
if (configOrError.getError() != null) {
throw new ResourceInvalidException(
"Failed to parse lb config for cluster '" + cluster.getName() + "': "
+ configOrError.getError());
}
updateBuilder.lbPolicyConfig(configOrError.getConfig(), lbPolicyConfig);
updateBuilder.filterMetadata(
ImmutableMap.copyOf(cluster.getMetadata().getFilterMetadataMap()));View on GitHub (pinned to 64daddc1f3)
Solutions
- Read the propagated errorDetail message to identify which cluster field the nested parser rejected
- Fix the corresponding cluster configuration on the management server
- Check grpc-java version support for the control plane's features (e.g. newer cluster fields)
Example fix
// before
AggregateCluster.newBuilder().addClusterNames("").build()
// after
AggregateCluster.newBuilder().addClusterNames("child_cluster_1").build() Defensive patterns
Strategy: try-catch
Try / catch
try {
cdsUpdate = xdsClusterResource.parseResource(args);
} catch (ResourceInvalidException e) {
// e.getMessage() carries the nested parser's errorDetail; surface it to config owners
logger.atWarning().log("CDS parse failed: %s", e.getMessage());
nackResource(e.getMessage());
} Prevention
- Keep per-type cluster configs (EDS/aggregate) within gRPC-supported shapes
- Read the propagated errorDetail to locate the offending field
- Test cluster configs against grpc-java's parser before rollout
When it happens
Trigger: Any of the per-type parsers (parseNonAggregateCluster, parseAggregateCluster, etc.) return a StructOrError whose errorDetail is non-null, e.g. invalid EDS config, missing load_assignment, bad LRS config.
Common situations: EDS cluster missing eds_cluster_config; aggregate cluster with empty/degenerate localities list; unsupported lb policy features for the cluster type.
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
- Cluster " + cluster.getName() + ": unspecified cluster disco
- unsupported ExtAuthz service type: only grpc_service is supp
- Invalid ring hash function: " + ringHash.getHashFunction()
- Custom LB config does not contain a JSON object
- Invalid header matcher config: [grpc-] prefixed header name
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/ab6f923c530b8682.
Report an issue: GitHub.