grpc/grpc-go · error

extauthz: empty grpc_service provided in config

Error message

extauthz: empty grpc_service provided in config %v

What it means

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.

Solutions

  1. Ensure the xDS server includes a grpc_service in the ExtAuthz config pointing to a valid authorization server
  2. If using HTTP-based authorization, note that the gRPC client-side ext_authz filter only supports grpc_service
  3. Verify the authorization server cluster reference is correct and the service is deployed
Defensive patterns

Strategy: validation

Validate before calling

// Ensure grpc_service is set before processing the ExtAuthz config.
if msg.GetGrpcService() == nil {
    return fmt.Errorf("ExtAuthz config must include grpc_service for client-side authorization")
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/ba6b3fb28b7c85c7. Report an issue: GitHub.

Appendix: 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 0c51461d27)