{"record":{"id":"15acff9d51dc3e4d","repo":"grpc/grpc-go","slug":"extproc-invalid-request-body-mode-v-want-q-or","errorCode":null,"errorMessage":"extproc: invalid request body mode %v: want %q or %q","messagePattern":"extproc: invalid request body mode (.+?): want %q or %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/extproc/ext_proc.go","lineNumber":98,"sourceCode":"func timeSince(t time.Time) time.Duration {\n\treturn iextproc.TimeSinceFunc(t)\n}\n\ntype builder struct{}\n\nfunc (builder) TypeURLs() []string {\n\treturn []string{\n\t\t\"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor\",\n\t\t\"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExtProcPerRoute\",\n\t}\n}\n\n// validateBodyProcessingMode ensures that the body processing mode is either\n// NONE or GRPC. Also ensures that if response body mode is GRPC then response\n// trailer mode must be SEND.\nfunc validateBodyProcessingMode(mode *v3procfilterpb.ProcessingMode) error {\n\tif m := mode.GetRequestBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {\n\t\treturn fmt.Errorf(\"extproc: invalid request body mode %v: want %q or %q\", m, \"NONE\", \"GRPC\")\n\t}\n\tif m := mode.GetResponseBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {\n\t\treturn fmt.Errorf(\"extproc: invalid response body mode %v: want %q or %q\", m, \"NONE\", \"GRPC\")\n\t}\n\tif mode.GetResponseBodyMode() == v3procfilterpb.ProcessingMode_GRPC && mode.GetResponseTrailerMode() != v3procfilterpb.ProcessingMode_SEND {\n\t\treturn fmt.Errorf(\"extproc: invalid response trailer mode %v: must be %q when response body mode is %q\", mode.GetResponseTrailerMode(), \"SEND\", \"GRPC\")\n\t}\n\treturn nil\n}\n\nfunc (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"extproc: error parsing config %v: unknown type %T, want *anypb.Any\", cfg, cfg)\n\t}\n\tmsg := new(v3procfilterpb.ExternalProcessor)\n\tif err := m.UnmarshalTo(msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"extproc: failed to unmarshal config %v: %v\", cfg, err)","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/extproc/ext_proc.go#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# xDS config - before\nprocessing_mode:\n  request_body_mode: STREAMED\n# after\nprocessing_mode:\n  request_body_mode: GRPC","handlingStrategy":"validation","validationCode":"// control-plane / config-author guard\nallowed := map[int32]bool{0: true /*NONE*/, 2: true /*GRPC*/}\nif !allowed[int32(cfg.ProcessingMode.RequestBodyMode.Number())] {\n  return fmt.Errorf(\"request_body_mode must be NONE or GRPC\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["grpc","xds","extproc","config","processing-mode"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}