{"record":{"id":"ba6b3fb28b7c85c7","repo":"grpc/grpc-go","slug":"extauthz-empty-grpc-service-provided-in-config-v","errorCode":null,"errorMessage":"extauthz: empty grpc_service provided in config %v","messagePattern":"extauthz: empty grpc_service provided in config (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/ext_authz/ext_authz.go","lineNumber":103,"sourceCode":"func grpcStatusCode(httpStatus int32) codes.Code {\n\tif code, ok := transport.HTTPStatusConvTab[int(httpStatus)]; ok {\n\t\treturn code\n\t}\n\treturn codes.Unknown\n}\n\nfunc (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"extauthz: error parsing config %v: unknown type %T, want *anypb.Any\", cfg, cfg)\n\t}\n\tmsg := new(v3extauthzpb.ExtAuthz)\n\tif err := m.UnmarshalTo(msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: failed to unmarshal config: %v\", err)\n\t}\n\n\tif msg.GetGrpcService() == nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: empty grpc_service provided in config %v\", cfg)\n\t}\n\tserver, err := parseGRPCServiceConfig(msg.GetGrpcService())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: failed to parse grpc_service: %v\", err)\n\t}\n\n\tfilterEnabled, err := parseFilterEnabled(msg.GetFilterEnabled())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar denyAtDisable bool\n\tif denyAtDisableFlag := msg.GetDenyAtDisable(); denyAtDisableFlag != nil {\n\t\tif denyAtDisableFlag.GetDefaultValue() == nil {\n\t\t\treturn nil, fmt.Errorf(\"extauthz: missing default_value in deny_at_disable\")\n\t\t}\n\t\tdenyAtDisable = denyAtDisableFlag.GetDefaultValue().GetValue()\n\t}","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/ext_authz/ext_authz.go#L85-L121","documentation":"The ExtAuthz configuration does not include a grpc_service field (ext_authz.go:102-103). The external authorization filter needs at least one backend service to forward authorization check requests to, and the gRPC client-side ext_authz filter specifically requires grpc_service.","triggerScenarios":"msg.GetGrpcService() returns nil because the xDS server sent an ExtAuthz config without grpc_service set. This can happen when only http_service is configured (which the gRPC client-side filter does not support) or when the config is incomplete.","commonSituations":"xDS server configures only http_service (which this client-side filter does not support) or neither service; misconfigured authorization backend reference; Envoy server-side proxy config mistakenly applied to a gRPC client-side xDS configuration.","solutions":["Ensure the xDS server includes a grpc_service in the ExtAuthz config pointing to a valid authorization server","If using HTTP-based authorization, note that the gRPC client-side ext_authz filter only supports grpc_service","Verify the authorization server cluster reference is correct and the service is deployed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure grpc_service is set before processing the ExtAuthz config.\nif msg.GetGrpcService() == nil {\n    return fmt.Errorf(\"ExtAuthz config must include grpc_service for client-side authorization\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include grpc_service in ExtAuthz configs for gRPC client-side usage","Validate ExtAuthz configs against client-side filter requirements before deployment","Do not apply server-side-only ExtAuthz configs (http_service) to gRPC client xDS","Document which ExtAuthz fields are supported on the client side"],"tags":["ext-authz","xds","http-filter","configuration","grpc-service"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}