{"record":{"id":"2f890df573361f77","repo":"grpc/grpc-java","slug":"unsupported-grpcservice-must-have-googlegrpc-got","errorCode":null,"errorMessage":"Unsupported: GrpcService must have GoogleGrpc, got: ${grpcServiceProto}","messagePattern":"Unsupported: GrpcService must have GoogleGrpc, got: (.+?)","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":88,"sourceCode":"  static final String GOOGLE_DEFAULT_CREDENTIALS_TYPE_URL =\n      \"type.googleapis.com/envoy.extensions.grpc_service.channel_credentials.\"\n          + \"google_default.v3.GoogleDefaultCredentials\";\n\n\n\n  /**\n   * Parses the {@link io.envoyproxy.envoy.config.core.v3.GrpcService} proto to create a\n   * {@link GrpcServiceConfig} instance.\n   *\n   * @param grpcServiceProto The proto to parse.\n   * @return A {@link GrpcServiceConfig} instance.\n   * @throws GrpcServiceParseException if the proto is invalid or uses unsupported features.\n   */\n  public static GrpcServiceConfig parse(GrpcService grpcServiceProto,\n      Bootstrapper.BootstrapInfo bootstrapInfo, Bootstrapper.ServerInfo serverInfo)\n      throws GrpcServiceParseException {\n    if (!grpcServiceProto.hasGoogleGrpc()) {\n      throw new GrpcServiceParseException(\n          \"Unsupported: GrpcService must have GoogleGrpc, got: \" + grpcServiceProto);\n    }\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        }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L70-L106","documentation":"Thrown by GrpcServiceConfigParser.parse when an xDS-received GrpcService proto carries no google_grpc field. grpc-java's xDS control plane only supports GoogleGrpc-style service configurations; an Envoy GrpcService specifying only grpc (Cc/EnvoyGrpc) or omitting both is unsupported and fails parsing.","triggerScenarios":"xDS management server sends a ConfigSource/GrpcService message where hasGoogleGrpc() is false — e.g. the LDS/CDS resource uses envoy.extensions...grpc_service with only the 'envoy_grpc' field populated.","commonSituations":"Pointing grpc-java at an Envoy-oriented xDS control plane (e.g. Envoy xDS server, Istio configs written for Envoy) that emits envoy_grpc instead of google_grpc.","solutions":["Update the xDS management server / control-plane resource so GrpcService uses the google_grpc field with server_uri.","If using Istio/Envoy tooling, ensure the generated resources target google_grpc for Java workloads.","Check the received LDS/CDS resource (enable xDS client logging) to confirm which GrpcService variant is sent."],"exampleFix":"// before (xDS resource proto)\ngrpc_service { envoy_grpc { cluster_name: \"xds_cluster\" } }\n// after\ngrpc_service { google_grpc { target_uri: \"xds.example.com:443\" } }","handlingStrategy":"try-catch","validationCode":"// Verify the received resource uses google_grpc before relying on it\nif (!grpcServiceProto.hasGoogleGrpc()) {\n  throw new IllegalStateException(\"xDS resource lacks google_grpc; fix control-plane resource\");\n}","typeGuard":"// Kotlin-style guard\nfun GrpcService.hasGoogleGrpcConfig(): Boolean = hasGoogleGrpc()","tryCatchPattern":"try {\n  GrpcServiceConfig cfg = GrpcServiceConfigParser.parse(grpcServiceProto, bootstrapInfo, serverInfo);\n} catch (GrpcServiceParseException e) {\n  logger.log(WARNING, \"Unsupported GrpcService from control plane: \" + e.getMessage());\n  // skip resource / fall back to last-known-good config\n}","preventionTips":["Ensure your xDS control plane emits google_grpc, not envoy_grpc","Test with a resource dump from the management server","For Envoy-oriented planes, switch to a google_grpc-capable config generator"],"tags":["xds","config-parser","unsupported","protobuf"],"backgroundTag":"unsupported-config-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"}