grpc/grpc-go · error
extproc: invalid request body mode
Error message
extproc: invalid request body mode %v: want %q or %q
What it means
Returned by validateBodyProcessingMode when ProcessingMode.request_body_mode is neither NONE nor GRPC. grpc-go's ext_proc client only supports NONE (do not send body) and GRPC (buffer whole gRPC messages); Envoy's STREAMED and BUFFERED modes are intentionally unsupported. Hit at ext_proc.go:97.
Solutions
- Set processing_mode.request_body_mode to NONE or GRPC in the xDS config.
- If you need streaming body processing, run Envoy as the data plane instead of grpc-go's built-in ext_proc.
- Confirm the grpc-go version supports ext_proc at all (gated by GRPC_XDS_EXTPROC env var / envconfig.XDSClientExtProcEnabled).
- Audit the control-plane template that emits processing_mode for hard-coded STREAMED/BUFFERED.
Example fix
# xDS config - before processing_mode: request_body_mode: STREAMED # after processing_mode: request_body_mode: GRPC
Defensive patterns
Strategy: validation
Validate before calling
// control-plane / config-author guard
allowed := map[int32]bool{0: true /*NONE*/, 2: true /*GRPC*/}
if !allowed[int32(cfg.ProcessingMode.RequestBodyMode.Number())] {
return fmt.Errorf("request_body_mode must be NONE or GRPC")
} Prevention
- Restrict request_body_mode to NONE or GRPC in control-plane schema validation.
- Do not reuse Envoy configs verbatim with grpc-go clients.
- Confirm ext_proc is enabled in grpc-go (envconfig.XDSClientExtProcEnabled).
- Test new configs against a grpc-go client before rollout.
When it happens
Trigger: An xDS ExternalProcessor config is applied whose processing_mode.request_body_mode is STREAMED or BUFFERED. ParseFilterConfig (or ParseFilterConfigOverride) calls validateBodyProcessingMode, which returns this error, and the resource is rejected.
Common situations: An Envoy-targeted config is reused verbatim against a grpc-go client; a control plane emits STREAMED by default; an operator switches body mode expecting streaming mutation support that grpc-go does not implement.
Related errors
- extproc: invalid response body mode
- extproc: invalid response trailer mode
- external processor sent an immediate response but immediate…
- external processor unexpectedly sent request body when…
- external processor unexpectedly sent response body when…
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/15acff9d51dc3e4d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:98
func timeSince(t time.Time) time.Duration {
return iextproc.TimeSinceFunc(t)
}
type builder struct{}
func (builder) TypeURLs() []string {
return []string{
"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor",
"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExtProcPerRoute",
}
}
// validateBodyProcessingMode ensures that the body processing mode is either
// NONE or GRPC. Also ensures that if response body mode is GRPC then response
// trailer mode must be SEND.
func validateBodyProcessingMode(mode *v3procfilterpb.ProcessingMode) error {
if m := mode.GetRequestBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {
return fmt.Errorf("extproc: invalid request body mode %v: want %q or %q", m, "NONE", "GRPC")
}
if m := mode.GetResponseBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {
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)View on GitHub (pinned to 0c51461d27)