grpc/grpc-go · error
extproc: empty grpc_service provided in config
Error message
extproc: empty grpc_service provided in config %v
What it means
Returned by ParseFilterConfig when the decoded ExternalProcessor message has a nil grpc_service field. The grpc_service tells the client where the external processor server lives (target URI, credentials); without it the filter cannot connect to a processor. Hit at ext_proc.go:125.
Solutions
- Populate grpc_service with a valid envoy.config.core.v3.GrpcService (at least a target URI).
- Use the google_grpc or envoy_grpc variant as appropriate for your environment.
- Add schema validation in the control plane requiring grpc_service for ext_proc filters.
- Diff the resource against a known-good ext_proc config.
Example fix
# before
# ExternalProcessor with grpc_service omitted
# after
grpc_service:
envoy_grpc:
cluster_name: ext-proc-cluster Defensive patterns
Strategy: validation
Validate before calling
// control-plane guard
if cfg.GetGrpcService() == nil {
return fmt.Errorf("ext_proc config requires grpc_service")
} Prevention
- Always populate grpc_service with a target and credentials.
- Add control-plane schema validation requiring grpc_service.
- Confirm the referenced cluster exists in the bootstrap.
- Diff against a known-good ext_proc config.
When it happens
Trigger: An xDS ExternalProcessor resource is sent without grpc_service populated. ParseFilterConfig checks msg.GetGrpcService() == nil and rejects the config.
Common situations: The grpc_service was templated from a variable that resolved empty; a config author relied on a non-existent default; the field was dropped during a proto refactor.
Related errors
- extproc: missing processing_mode in config
- external processor sent an immediate response but immediate…
- extproc: error parsing config
- extproc: error parsing override
- extproc: failed to parse grpc_service
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/294cd0801a466108.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:126
func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
m, ok := cfg.(*anypb.Any)
if !ok {
return nil, fmt.Errorf("extproc: error parsing config %v: unknown type %T, want *anypb.Any", cfg, cfg)
}
msg := new(v3procfilterpb.ExternalProcessor)
if err := m.UnmarshalTo(msg); err != nil {
return nil, fmt.Errorf("extproc: failed to unmarshal config %v: %v", cfg, err)
}
if msg.GetProcessingMode() == nil {
return nil, fmt.Errorf("extproc: missing processing_mode in config %v", cfg)
}
if err := validateBodyProcessingMode(msg.GetProcessingMode()); err != nil {
return nil, err
}
if msg.GetGrpcService() == nil {
return nil, fmt.Errorf("extproc: empty grpc_service provided in config %v", cfg)
}
server, err := iextproc.ParseGRPCServiceConfig(msg.GetGrpcService())
if err != nil {
return nil, fmt.Errorf("extproc: failed to parse grpc_service %v", err)
}
mutationRules, err := httpfilter.HeaderMutationRulesFromProto(msg.GetMutationRules())
if err != nil {
return nil, err
}
var allowedHeaders, disallowedHeaders []matcher.StringMatcher
if allowed := msg.GetForwardRules().GetAllowedHeaders(); allowed != nil {
allowedHeaders, err = httpfilter.ConvertStringMatchers(allowed.GetPatterns())
if err != nil {
return nil, err
}
}View on GitHub (pinned to 0c51461d27)