{"record":{"id":"b23702cef185e561","repo":"grpc/grpc-java","slug":"invalid-initial-metadata-header-key","errorCode":null,"errorMessage":"Invalid initial metadata header: ${key}","messagePattern":"Invalid initial metadata header: (.+?)","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":108,"sourceCode":"    }\n    GrpcServiceConfig.GoogleGrpcConfig googleGrpcConfig =\n        parseGoogleGrpcConfig(grpcServiceProto.getGoogleGrpc(), bootstrapInfo, serverInfo);\n\n    GrpcServiceConfig.Builder builder = GrpcServiceConfig.builder().googleGrpc(googleGrpcConfig);\n\n    ImmutableList.Builder<HeaderValue> initialMetadata = ImmutableList.builder();\n    for (io.envoyproxy.envoy.config.core.v3.HeaderValue header : grpcServiceProto\n        .getInitialMetadataList()) {\n      String key = header.getKey();\n      HeaderValue headerValue;\n      try {\n        if (key.endsWith(Metadata.BINARY_HEADER_SUFFIX)) {\n          headerValue = HeaderValue.create(key, header.getRawValue());\n        } else {\n          headerValue = HeaderValue.create(key, header.getValue());\n        }\n      } catch (IllegalArgumentException e) {\n        throw new GrpcServiceParseException(\"Invalid initial metadata header: \" + key, e);\n      }\n      if (HeaderValueValidationUtils.isDisallowed(headerValue)) {\n        throw new GrpcServiceParseException(\"Invalid initial metadata header: \" + key);\n      }\n      initialMetadata.add(headerValue);\n    }\n    builder.initialMetadata(initialMetadata.build());\n\n    if (grpcServiceProto.hasTimeout()) {\n      com.google.protobuf.Duration timeout = grpcServiceProto.getTimeout();\n      if (!Durations.isValid(timeout) || Durations.compare(timeout, Durations.ZERO) <= 0) {\n        throw new GrpcServiceParseException(\"Timeout must be strictly positive and valid\");\n      }\n      builder.timeout(Duration.ofSeconds(timeout.getSeconds(), timeout.getNanos()));\n    }\n    return builder.build();\n  }\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L90-L126","documentation":"Thrown by GrpcServiceConfigParser.parse when an initial_metadata header from the GrpcService proto cannot be converted into a Metadata.HeaderValue — HeaderValue.create threw IllegalArgumentException (e.g. invalid header name characters) — or the header is rejected by HeaderValueValidationUtils.isDisallowed. gRPC forbids malformed or reserved headers in injected metadata.","triggerScenarios":"xDS GrpcService.google_grpc.call_credentials or channel config includes initial_metadata whose key is malformed (invalid characters, wrong case rules for binary headers missing the -bin suffix handling) or whose value fails validation; also fires when the header is on the disallowed list (e.g. reserved headers like :authority, host, content-length).","commonSituations":"Control-plane configuration injecting headers such as 'host', 'authorization' in disallowed forms, or binary values sent as regular (non -bin) headers; typos producing illegal ASCII control characters in keys.","solutions":["Fix the header key/value in the xDS resource: use lowercase, valid header names and legal values.","Remove or rename disallowed/reserved headers (e.g. host, content-length) from initial_metadata.","For binary data, use a key ending in '-bin' and supply raw_value instead of value.","Inspect the GrpcService proto received from the control plane to identify the offending key named in the message."],"exampleFix":"// before (xDS resource)\ninitial_metadata { key: \"Host\" value: \"example.com\" }\n// after\ninitial_metadata { key: \"x-custom-host\" value: \"example.com\" }","handlingStrategy":"validation","validationCode":"// Pre-validate header keys before pushing them via xDS\nString key = header.getKey();\nif (key == null || key.isEmpty() || !key.chars().allMatch(c ->\n    (c >= 'a' && c <= '9' && c != ':') || c == '-' || (c >= '0' && c <= '9'))) {\n  throw new IllegalArgumentException(\"bad metadata header key: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  config = GrpcServiceConfigParser.parse(proto, bootstrapInfo, serverInfo);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().startsWith(\"Invalid initial metadata header\")) {\n    logger.log(WARNING, \"Rejecting resource with bad header: \" + e.getMessage());\n  }\n}","preventionTips":["Use lowercase, RFC 7230-compliant header names in xDS metadata","Use '-bin' suffixed keys with raw_value for binary data","Avoid reserved gRPC/HTTP2 headers in initial_metadata"],"tags":["xds","metadata","headers","validation"],"backgroundTag":"invalid-argument-value","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"}