grpc/grpc-java · error · ResourceInvalidException
Failed to parse metadata key: %s, type: %s. Error: %s
Error message
Failed to parse metadata key: %s, type: %s. Error: %s
What it means
xDS node/filter metadata values are typed Any messages that must be parsed by a registered MetadataValueParser for their type_url. If the registered parser rejects the value (throws ResourceInvalidException), parseMetadata rethrows with the key, type_url, and underlying error so the offending metadata entry is identified.
Source
Thrown at xds/src/main/java/io/grpc/xds/MetadataRegistry.java:90
* @param metadata the {@link Metadata} containing the fields to parse.
* @return an immutable map of parsed metadata.
* @throws ResourceInvalidException if parsing {@code typed_filter_metadata} fails.
*/
public ImmutableMap<String, Object> parseMetadata(Metadata metadata)
throws ResourceInvalidException {
ImmutableMap.Builder<String, Object> parsedMetadata = ImmutableMap.builder();
// Process typed_filter_metadata
for (Map.Entry<String, Any> entry : metadata.getTypedFilterMetadataMap().entrySet()) {
String key = entry.getKey();
Any value = entry.getValue();
MetadataValueParser parser = findParser(value.getTypeUrl());
if (parser != null) {
try {
Object parsedValue = parser.parse(value);
parsedMetadata.put(key, parsedValue);
} catch (ResourceInvalidException e) {
throw new ResourceInvalidException(
String.format("Failed to parse metadata key: %s, type: %s. Error: %s",
key, value.getTypeUrl(), e.getMessage()), e);
}
}
}
// building once to reuse in the next loop
ImmutableMap<String, Object> intermediateParsedMetadata = parsedMetadata.build();
// Process filter_metadata for remaining keys
for (Map.Entry<String, Struct> entry : metadata.getFilterMetadataMap().entrySet()) {
String key = entry.getKey();
if (!intermediateParsedMetadata.containsKey(key)) {
Struct structValue = entry.getValue();
Object jsonValue = ProtobufJsonConverter.convertToJson(structValue);
parsedMetadata.put(key, jsonValue);
}
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Read the nested 'Error:' message to find the parser's specific complaint, then fix that metadata value on the control plane
- Ensure filter metadata matches the proto schema for the given type_url (validate with Envoy config dump)
- Align envoy protos versions between management server and client dependencies
- Remove or fix the offending metadata key in the LDS/CDS resource
Example fix
# before (typed filter metadata with wrong field type)
"com.foo": {"max_fault_percent": "fifty"}
# after
"com.foo": {"max_fault_percent": 50} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate typed metadata before attaching it to the resource: Object parsed = parserFor(typeUrl).parse(anyValue); // throws with schema detail if invalid
Try / catch
try {
Map<String, ?> metadata = registry.parseFilterMetadata(metadataMap);
} catch (ResourceInvalidException e) {
logger.warning("Metadata rejected: " + e.getMessage()); // names key, type_url, and cause
// skip resource or strip the offending metadata key
} Prevention
- Ensure filter metadata matches the proto schema for its type_url
- Keep envoy protos versions identical on server and client
- Validate metadata with Envoy config dump before ADS push
When it happens
Trigger: parsedFilterMetadata or parseLocalityLbEndpoints encounter metadata whose Any payload fails the parser for its type_url — e.g. a filter metadata Struct that does not match the expected proto schema, or an unparseable value for a well-known type.
Common situations: Control plane emitting filter metadata that doesn't match the typed extension schema (e.g. RBAC or Fault filter metadata fields with wrong types); version skew between envoy protos on server and client; typos in metadata keys expected to hold typed values.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unknown permission rule case: " + permission.getRuleCase()
- Unknown principal identifier case: " + principal.getIdentifi
- Unknown path matcher rule type: " + proto.getRuleCase()
- Invalid message type: " + unpackedMessage.getClass()
- Failed to parse xDS filter metadata for cluster '" + cluster
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/a7079a22c02fc999.
Report an issue: GitHub.