{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/extproc/ext_proc.go#L80-L116","documentation":"Raised by validateBodyProcessingMode (ext_proc.go:98) when the ExternalProcessor processing_mode.request_body_mode is anything other than NONE or GRPC. The gRPC ext_proc implementation only supports NONE (skip body) and GRPC (stream gRPC messages); other Envoy modes (STREAMED, BUFFERED, BUFFERED_PARTIAL, FULL_DUPLEX_STREAMED) are rejected during config validation, so the LDS resource is NACKed.","triggerScenarios":"msg.GetProcessingMode().GetRequestBodyMode() returns a value that is neither ProcessingMode_NONE nor ProcessingMode_GRPC at ext_proc.go:97.","commonSituations":"Reusing an Envoy-oriented ext_proc config that sets request_body_mode: STREAMED (Envoy's default-ish) without trimming it for gRPC; copying an HTTP ext_proc config verbatim into an xDS resource consumed by a gRPC client.","solutions":["Set request_body_mode to NONE (no request body processing) or GRPC (per-gRPC-message body processing).","Remove any STREAMED/BUFFERED/FULL_DUPLEX_STREAMED values copied from an Envoy HTTP config.","Re-apply the resource and confirm the client ACKs it."],"exampleFix":"// before\n//   processing_mode: { request_body_mode: STREAMED }   // -> error 372\n//\n// after\n//   processing_mode: { request_body_mode: GRPC }   // (or NONE)","handlingStrategy":"validation","validationCode":"// Validate request body mode exactly like validateBodyProcessingMode (ext_proc.go:96-99).\nfunc validateRequestBodyMode(pm *v3procfilterpb.ProcessingMode) error {\n    if m := pm.GetRequestBodyMode(); m != v3procfilterpb.ProcessingMode_NONE && m != v3procfilterpb.ProcessingMode_GRPC {\n        return fmt.Errorf(\"extproc: invalid request body mode %v: want %%q or %%q\", m)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["For gRPC ext_proc, only use request_body_mode NONE or GRPC.","When adapting Envoy HTTP ext_proc configs, strip STREAMED/BUFFERED body modes.","Add a CI check that rejects unsupported processing_mode enum values for gRPC-bound xDS resources."],"tags":["grpc","xds","config","ext-proc","processing-mode"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}