{"record":{"id":"4692c211cbbadb1c","repo":"grpc/grpc-java","slug":"unsupported-extauthz-service-type-only-grpc-servi","errorCode":null,"errorMessage":"unsupported ExtAuthz service type: only grpc_service is supported","messagePattern":"unsupported ExtAuthz service type: only grpc_service is supported","errorType":"validation","errorClass":"ExtAuthzParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/ExtAuthzConfigParser.java","lineNumber":52,"sourceCode":" * Parser for {@link io.envoyproxy.envoy.extensions.filters.http.ext_authz.v3.ExtAuthz}.\n */\nfinal class ExtAuthzConfigParser {\n\n  private ExtAuthzConfigParser() {}\n\n  /**\n   * Parses the {@link io.envoyproxy.envoy.extensions.filters.http.ext_authz.v3.ExtAuthz} proto to\n   * create an {@link ExtAuthzConfig} instance.\n   *\n   * @param extAuthzProto The ext_authz proto to parse.\n   * @return An {@link ExtAuthzConfig} instance.\n   * @throws ExtAuthzParseException if the proto is invalid or contains unsupported features.\n   */\n  public static ExtAuthzConfig parse(\n      ExtAuthz extAuthzProto, BootstrapInfo bootstrapInfo, ServerInfo serverInfo)\n      throws ExtAuthzParseException {\n    if (!extAuthzProto.hasGrpcService()) {\n      throw new ExtAuthzParseException(\n          \"unsupported ExtAuthz service type: only grpc_service is supported\");\n    }\n    GrpcServiceConfig grpcServiceConfig;\n    try {\n      grpcServiceConfig =\n          GrpcServiceConfigParser.parse(extAuthzProto.getGrpcService(), bootstrapInfo, serverInfo);\n    } catch (GrpcServiceParseException e) {\n      throw new ExtAuthzParseException(\"Failed to parse GrpcService config: \" + e.getMessage(), e);\n    }\n    ExtAuthzConfig.Builder builder = ExtAuthzConfig.builder().grpcService(grpcServiceConfig)\n        .failureModeAllow(extAuthzProto.getFailureModeAllow())\n        .failureModeAllowHeaderAdd(extAuthzProto.getFailureModeAllowHeaderAdd())\n        .includePeerCertificate(extAuthzProto.getIncludePeerCertificate())\n        .denyAtDisable(extAuthzProto.getDenyAtDisable().getDefaultValue().getValue());\n\n    if (extAuthzProto.hasFilterEnabled()) {\n      try {\n        builder.filterEnabled(","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/ExtAuthzConfigParser.java#L34-L70","documentation":"When parsing an Envoy ext_authz (external authorization) network filter config, gRPC xDS only supports the grpc_service variant for contacting the authorization server. If the ExtAuthz proto carries any other service type (e.g., http_service / http_uri) or no service at all, ExtAuthzConfigParser.parse throws ExtAuthzParseException with 'unsupported ExtAuthz service type: only grpc_service is supported'. The filter config is rejected and the associated xDS configuration update fails.","triggerScenarios":"An Envoy ext_authz filter in the received LDS/RDS (HTTP filter) configuration sets ext_authz.http_service (or leaves grpc_service unset), and the config is parsed via ExtAuthzConfigParser.parse during xDS config processing.","commonSituations":"Reusing an Envoy-side ext_authz config that points at an HTTP authorization service; forgetting to define grpc_service in the filter config; migrating Envoy HTTP-filter configs to gRPC-Java xDS which only implements the gRPC authz transport.","solutions":["Rewrite the ext_authz filter config to use grpc_service, specifying the xDS cluster name, authority, and timeout for the gRPC authorization server.","Ensure the referenced cluster for the gRPC authz service exists in the CDS configuration.","If only an HTTP authorization server exists, front it with a gRPC adapter or use an Envoy proxy for conversion, since gRPC-Java will not accept http_service.","Check the config with the Envoy/protobuf schema (ext_authz.proto) to confirm ext_authz.grpc_service is set before deploying."],"exampleFix":"// before (rejected)\next_authz {\n  http_service { server_uri { uri: \"auth:9000\" } }\n}\n// after\next_authz {\n  grpc_service {\n    envoy_grpc { cluster_name: \"authz-cluster\" }\n    timeout { seconds: 1 }\n  }\n}","handlingStrategy":"validation","validationCode":"// validate before applying xDS config\nif (!extAuthzProto.hasGrpcService()) {\n  throw new IllegalArgumentException(\"ext_authz requires grpc_service\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  ExtAuthzConfig cfg = ExtAuthzConfigParser.parse(proto, bootstrap, serverInfo);\n} catch (ExtAuthzParseException e) {\n  logger.error(\"Rejecting ext_authz config: \" + e.getMessage());\n  // keep serving with previous config (NACK the update)\n}","preventionTips":["Always configure ext_authz with grpc_service (envoy_grpc cluster + timeout), never http_service.","Ensure the referenced authz cluster exists in CDS.","Validate Envoy filter configs against ext_authz.proto before deploying to gRPC-Java xDS.","Watch xDS client logs for NACKed LDS/RDS updates when migrating Envoy configs."],"tags":["grpc","xds","extauthz","config-validation"],"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"}