grpc/grpc-go · error
extauthz: empty grpc_service provided in config %v
Error message
extauthz: empty grpc_service provided in config %v
What it means
Raised by ParseFilterConfig (ext_authz.go:103) after the ExtAuthz proto is successfully unmarshaled but its grpc_service field is unset (nil). External authorization requires a backend gRPC service to send Check requests to, so a config with no grpc_service is unusable and the resource is rejected.
Source
Thrown at internal/xds/httpfilter/ext_authz/ext_authz.go:103
func grpcStatusCode(httpStatus int32) codes.Code {
if code, ok := transport.HTTPStatusConvTab[int(httpStatus)]; ok {
return code
}
return codes.Unknown
}
func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
m, ok := cfg.(*anypb.Any)
if !ok {
return nil, fmt.Errorf("extauthz: error parsing config %v: unknown type %T, want *anypb.Any", cfg, cfg)
}
msg := new(v3extauthzpb.ExtAuthz)
if err := m.UnmarshalTo(msg); err != nil {
return nil, fmt.Errorf("extauthz: failed to unmarshal config: %v", err)
}
if msg.GetGrpcService() == nil {
return nil, fmt.Errorf("extauthz: empty grpc_service provided in config %v", cfg)
}
server, err := parseGRPCServiceConfig(msg.GetGrpcService())
if err != nil {
return nil, fmt.Errorf("extauthz: failed to parse grpc_service: %v", err)
}
filterEnabled, err := parseFilterEnabled(msg.GetFilterEnabled())
if err != nil {
return nil, err
}
var denyAtDisable bool
if denyAtDisableFlag := msg.GetDenyAtDisable(); denyAtDisableFlag != nil {
if denyAtDisableFlag.GetDefaultValue() == nil {
return nil, fmt.Errorf("extauthz: missing default_value in deny_at_disable")
}
denyAtDisable = denyAtDisableFlag.GetDefaultValue().GetValue()
}View on GitHub (pinned to 03255a9237)
Solutions
- Add a grpc_service block to the ext_authz filter config in your control-plane/LDS resource (gRPC's implementation requires the gRPC variant, not http_service).
- Verify the grpc_service uses the google_grpc target specifier with a non-empty target_uri, since parseGRPCServiceConfig may reject envoy_grpc.
- Re-apply the listener and confirm the xDS resource is ACKed (no NACK) by the gRPC client.
Example fix
// before
// ext_authz: { } // grpc_service omitted -> error 361
//
// after
// ext_authz: {
// grpc_service: {
// google_grpc: { target_uri: "authz-server:9091" }
// }
// } Defensive patterns
Strategy: validation
Validate before calling
// Ensure the ExtAuthz config carries a grpc_service (ext_authz.go:102-104).
func ensureGrpcService(cfg *v3extauthzpb.ExtAuthz) error {
if cfg.GetGrpcService() == nil {
return fmt.Errorf("ext_authz: grpc_service must be set")
}
return nil
} Prevention
- Treat grpc_service as required in any ext_authz control-plane template/schema.
- Remember gRPC's ext_authz only supports grpc_service (google_grpc); http_service alone is not accepted.
- Add a policy-as-code check (OPA/kyverno) that rejects ext_authz filters without a grpc_service.
When it happens
Trigger: An LDS HTTP filter typed_config that unmarshals to a valid ExtAuthz whose oneof Services is left unset, i.e. msg.GetGrpcService() == nil at ext_authz.go:102.
Common situations: An Envoy filter config that only sets http_service (not yet supported by gRPC's ext_authz) and omits grpc_service; a control-plane template with a typo or a conditional that drops the grpc_service block; a partially-rendered config during a rollout.
Related errors
- extauthz: failed to parse grpc_service: %v
- extauthz: missing default_value in filter_enabled
- extauthz: failed to unmarshal config: %v
- extauthz: missing default_value in deny_at_disable
- extauthz: error parsing override config %v: unknown type %T,
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/ba6b3fb28b7c85c7.
Report an issue: GitHub.