grpc/grpc-java · error · ResourceInvalidException
Failed to parse xDS filter metadata for cluster '" + cluster
Error message
Failed to parse xDS filter metadata for cluster '" + cluster.getName() + "': " + e.getMessage()
What it means
processCluster parses the cluster's xDS filter metadata through the MetadataRegistry. If parsing raises ResourceInvalidException (unknown or malformed filter metadata entries), it is re-thrown with the cluster name and original message attached so the offending CDS resource is identifiable.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:186
= 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()));
try {
MetadataRegistry registry = MetadataRegistry.getInstance();
ImmutableMap<String, Object> parsedFilterMetadata =
registry.parseMetadata(cluster.getMetadata());
updateBuilder.parsedMetadata(parsedFilterMetadata);
} catch (ResourceInvalidException e) {
throw new ResourceInvalidException(
"Failed to parse xDS filter metadata for cluster '" + cluster.getName() + "': "
+ e.getMessage(), e);
}
return updateBuilder.build();
}
private static StructOrError<CdsUpdate.Builder> parseAggregateCluster(Cluster cluster) {
String clusterName = cluster.getName();
Cluster.CustomClusterType customType = cluster.getClusterType();
String typeName = customType.getName();
if (!typeName.equals(AGGREGATE_CLUSTER_TYPE_NAME)) {
return StructOrError.fromError(
"Cluster " + clusterName + ": unsupported custom cluster type: " + typeName);
}
io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig clusterConfig;
try {
clusterConfig = unpackCompatibleType(customType.getTypedConfig(),View on GitHub (pinned to 64daddc1f3)
Solutions
- Remove or correct unsupported filter metadata entries from the cluster's metadata on the management server
- Only attach filter metadata that gRPC's MetadataRegistry understands for the cluster
- Upgrade grpc-java so the registry recognizes the newer filter metadata types
Example fix
// before
metadata: {filter_metadata: {envoy.filters.http.unknown_filter: {foo: 1}}}
// after
metadata: {filter_metadata: {envoy.filters.http.rbac: {rules: <valid RBAC struct>}}} Defensive patterns
Strategy: try-catch
Validate before calling
try {
MetadataRegistry.getInstance().parseMetadata(cluster.getMetadata());
} catch (ResourceInvalidException e) {
// fix or strip metadata before publishing
} Try / catch
try {
cdsUpdate = xdsClusterResource.parseResource(args);
} catch (ResourceInvalidException e) {
if (e.getMessage().contains("filter metadata")) {
logger.atWarning().log("Cluster %s has unsupported metadata", clusterName);
}
} Prevention
- Only attach filter metadata gRPC's registry understands
- Validate metadata with MetadataRegistry before publishing clusters
- Avoid copying Envoy HTTP-filter metadata onto gRPC clusters verbatim
When it happens
Trigger: A Cluster's metadata map contains filter metadata keys/values that MetadataRegistry.parseMetadata cannot interpret — e.g. malformed envoy.filters.http.* structs or unknown filter names.
Common situations: Clusters carrying Envoy HTTP filter metadata not relevant/known to gRPC; management server emitting metadata with wrong value types (struct vs list); newly introduced filters sent to older clients.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unsupported ExtAuthz service type: only grpc_service is supp
- Invalid ring hash function: " + ringHash.getHashFunction()
- Custom LB config does not contain a JSON object
- Failed to parse metadata key: %s, type: %s. Error: %s
- Invalid header matcher config: [grpc-] prefixed header name
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/4925b75f08cd6e98.
Report an issue: GitHub.