grpc/grpc-java · error · ResourceInvalidException
Cluster " + cluster.getName() + ": unspecified cluster disco
Error message
Cluster " + cluster.getName() + ": unspecified cluster discovery type
What it means
When parsing a Cluster proto, processCluster switches on the cluster_type oneof. If the discovery type is CLUSTERDISCOVERYTYPE_NOT_SET (or an unrecognized value), the cluster does not declare how it is discovered (STATIC, STRICT_DNS, EDS, LOGICAL_DNS, or AGGREGATE), so parsing throws ResourceInvalidException.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:156
@VisibleForTesting
static CdsUpdate processCluster(Cluster cluster,
Set<String> certProviderInstances,
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());
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Set a valid discovery type on the cluster config at the management server (e.g. EDS with eds_cluster_config, or STATIC with load_assignment)
- Update the xDS control plane so emitted clusters always populate the cluster_type oneof
- Add validation on the server before publishing CDS resources
Example fix
// before
Cluster.newBuilder().setName("cluster1").build()
// after
Cluster.newBuilder().setName("cluster1")
.setType(Cluster.DiscoveryType.EDS)
.setEdsClusterConfig(Cluster.EdsClusterConfig.newBuilder().setEdsServiceName("cluster1"))
.build() Defensive patterns
Strategy: validation
Validate before calling
if (cluster.getClusterTypeCase() == Cluster.ClusterTypeCase.CLUSTERDISCOVERYTYPE_NOT_SET) {
throw new ResourceInvalidException("Cluster " + cluster.getName() + " has no discovery type");
} Type guard
boolean hasDiscoveryType(Cluster c) {
return c.getClusterTypeCase() != Cluster.ClusterTypeCase.CLUSTERDISCOVERYTYPE_NOT_SET;
} Try / catch
try {
cdsUpdate = xdsClusterResource.parseResource(args);
} catch (ResourceInvalidException e) {
logger.atWarning().log("Cluster rejected: %s", e.getMessage());
return Status.INVALID_ARGUMENT.withDescription(e.getMessage()).asException();
} Prevention
- Always set type (or cluster_type for aggregates) on cluster configs
- Validate Cluster protos on the control plane before publishing
- Cover emitted clusters with schema checks in CI
When it happens
Trigger: The xDS server sends a Cluster message with neither server_discovery_type, cluster_type, nor the EDS fields populated, i.e. the oneof is unset.
Common situations: Control-plane bugs emitting empty cluster protos; hand-crafted test fixtures missing cluster_type; proto serialization dropping default-valued fields when the server builds the Cluster incorrectly.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- structOrError.getErrorDetail()
- 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/90c80c578a05f6ae.
Report an issue: GitHub.