grpc/grpc-go · error
extproc: missing processing_mode in config
Error message
extproc: missing processing_mode in config %v
What it means
Returned by ParseFilterConfig when the decoded ExternalProcessor message has a nil processing_mode field. processing_mode is required because it defines which parts of the request/response are sent to the external processor; without it the filter cannot operate. Hit at ext_proc.go:118.
Solutions
- Populate processing_mode in the ExternalProcessor config with explicit request/response modes.
- If the control plane has a defaulting layer, ensure it sets processing_mode before emitting.
- Validate the resource with protoc/grpcurl-xds before applying.
- Cross-check the field against the proto definition your control plane compiles.
Example fix
# before # ExternalProcessor with no processing_mode # after processing_mode: request_header_mode: SEND response_header_mode: SEND request_body_mode: NONE response_body_mode: NONE response_trailer_mode: SKIP
Defensive patterns
Strategy: validation
Validate before calling
// control-plane guard
if cfg.GetProcessingMode() == nil {
return fmt.Errorf("ext_proc config requires processing_mode")
} Prevention
- Always populate processing_mode in the ExternalProcessor config.
- Add control-plane schema validation for the required field.
- Validate resources with protoc before applying.
- Diff new configs against a known-good baseline.
When it happens
Trigger: An xDS ExternalProcessor resource is sent with no processing_mode populated (the field is optional in proto3). ParseFilterConfig detects msg.GetProcessingMode() == nil and rejects the config.
Common situations: A minimal config template omitted processing_mode assuming a default; a control-plane upgrade reset optional fields; the resource was hand-authored and missed the field.
Related errors
- extproc: empty grpc_service provided 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/76aa63827537417d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:119
return fmt.Errorf("extproc: invalid response body mode %v: want %q or %q", m, "NONE", "GRPC")
}
if mode.GetResponseBodyMode() == v3procfilterpb.ProcessingMode_GRPC && mode.GetResponseTrailerMode() != v3procfilterpb.ProcessingMode_SEND {
return fmt.Errorf("extproc: invalid response trailer mode %v: must be %q when response body mode is %q", mode.GetResponseTrailerMode(), "SEND", "GRPC")
}
return nil
}
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
}
View on GitHub (pinned to 0c51461d27)