{"record":{"id":"6166a07e87a144b5","repo":"grpc/grpc-java","slug":"invalid-initial-metadata-header-key-6166a0","errorCode":null,"errorMessage":"Invalid initial metadata header: \" + key","messagePattern":"Invalid initial metadata header: \" \\+ key","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":111,"sourceCode":"\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\n  /**\n   * Parses the {@link io.envoyproxy.envoy.config.core.v3.GrpcService.GoogleGrpc} proto to create a\n   * {@link GrpcServiceConfig.GoogleGrpcConfig} instance.","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L93-L129","documentation":"Second throw site with the same message as error 294, but without a cause: HeaderValue.create succeeded yet HeaderValueValidationUtils.isDisallowed returned true, meaning the header is structurally valid but on gRPC's disallowed header list. Injecting such headers via xDS metadata is rejected to preserve protocol invariants.","triggerScenarios":"xDS GrpcService initial_metadata contains a well-formed header that gRPC disallows (reserved headers, restricted names). Distinct from 294 in that no IllegalArgumentException occurred — the header parses fine but is policy-forbidden.","commonSituations":"Control plane trying to inject 'te', 'content-type', 'host', or connection-level headers through initial_metadata; security policies forbidding credential headers being pushed via xDS.","solutions":["Remove the disallowed header from initial_metadata in the xDS resource.","Choose a custom application header name (e.g. prefix with x-) that passes validation.","Consult HeaderValueValidationUtils / gRPC metadata spec for the disallowed header list."],"exampleFix":"// before\ninitial_metadata { key: \"content-type\" value: \"application/grpc\" }\n// after\ninitial_metadata { key: \"x-content-type-hint\" value: \"application/grpc\" }","handlingStrategy":"validation","validationCode":"// Check headers against disallowed list before configuring control plane\nHeaderValue hv = HeaderValue.create(key, value);\nif (HeaderValueValidationUtils.isDisallowed(hv)) {\n  throw new IllegalArgumentException(\"header disallowed by gRPC: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  config = GrpcServiceConfigParser.parse(proto, bootstrapInfo, serverInfo);\n} catch (GrpcServiceParseException e) {\n  logger.log(WARNING, \"Resource rejected due to disallowed header: \" + e.getMessage());\n  // request control plane to fix metadata\n}","preventionTips":["Never inject reserved headers (host, te, content-type, content-length) via xDS","Prefix custom headers with x-","Review control-plane metadata templates against gRPC's disallowed header list"],"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"}