{"record":{"id":"4925b75f08cd6e98","repo":"grpc/grpc-java","slug":"failed-to-parse-xds-filter-metadata-for-cluster","errorCode":null,"errorMessage":"Failed to parse xDS filter metadata for cluster '\" + cluster.getName() + \"': \" + e.getMessage()","messagePattern":"Failed to parse xDS filter metadata for cluster '\" \\+ cluster\\.getName\\(\\) \\+ \"': \" \\+ e\\.getMessage\\(\\)","errorType":"validation","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsClusterResource.java","lineNumber":186,"sourceCode":"        = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(\n            ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);\n    if (configOrError.getError() != null) {\n      throw new ResourceInvalidException(\n          \"Failed to parse lb config for cluster '\" + cluster.getName() + \"': \"\n          + configOrError.getError());\n    }\n\n    updateBuilder.lbPolicyConfig(configOrError.getConfig(), lbPolicyConfig);\n    updateBuilder.filterMetadata(\n        ImmutableMap.copyOf(cluster.getMetadata().getFilterMetadataMap()));\n\n    try {\n      MetadataRegistry registry = MetadataRegistry.getInstance();\n      ImmutableMap<String, Object> parsedFilterMetadata =\n          registry.parseMetadata(cluster.getMetadata());\n      updateBuilder.parsedMetadata(parsedFilterMetadata);\n    } catch (ResourceInvalidException e) {\n      throw new ResourceInvalidException(\n          \"Failed to parse xDS filter metadata for cluster '\" + cluster.getName() + \"': \"\n              + e.getMessage(), e);\n    }\n\n    return updateBuilder.build();\n  }\n\n  private static StructOrError<CdsUpdate.Builder> parseAggregateCluster(Cluster cluster) {\n    String clusterName = cluster.getName();\n    Cluster.CustomClusterType customType = cluster.getClusterType();\n    String typeName = customType.getName();\n    if (!typeName.equals(AGGREGATE_CLUSTER_TYPE_NAME)) {\n      return StructOrError.fromError(\n          \"Cluster \" + clusterName + \": unsupported custom cluster type: \" + typeName);\n    }\n    io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig clusterConfig;\n    try {\n      clusterConfig = unpackCompatibleType(customType.getTypedConfig(),","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsClusterResource.java#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmetadata: {filter_metadata: {envoy.filters.http.unknown_filter: {foo: 1}}}\n// after\nmetadata: {filter_metadata: {envoy.filters.http.rbac: {rules: <valid RBAC struct>}}}","handlingStrategy":"try-catch","validationCode":"try {\n  MetadataRegistry.getInstance().parseMetadata(cluster.getMetadata());\n} catch (ResourceInvalidException e) {\n  // fix or strip metadata before publishing\n}","typeGuard":null,"tryCatchPattern":"try {\n  cdsUpdate = xdsClusterResource.parseResource(args);\n} catch (ResourceInvalidException e) {\n  if (e.getMessage().contains(\"filter metadata\")) {\n    logger.atWarning().log(\"Cluster %s has unsupported metadata\", clusterName);\n  }\n}","preventionTips":["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"],"tags":["grpc","xds","metadata","config-validation"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}