{"record":{"id":"76aa63827537417d","repo":"grpc/grpc-go","slug":"extproc-missing-processing-mode-in-config-v","errorCode":null,"errorMessage":"extproc: missing processing_mode in config %v","messagePattern":"extproc: missing processing_mode in config (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/extproc/ext_proc.go","lineNumber":119,"sourceCode":"\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)\n\t}\n\tif msg.GetProcessingMode() == nil {\n\t\treturn nil, fmt.Errorf(\"extproc: missing processing_mode in config %v\", cfg)\n\t}\n\tif err := validateBodyProcessingMode(msg.GetProcessingMode()); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif msg.GetGrpcService() == nil {\n\t\treturn nil, fmt.Errorf(\"extproc: empty grpc_service provided in config %v\", cfg)\n\t}\n\tserver, err := iextproc.ParseGRPCServiceConfig(msg.GetGrpcService())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extproc: failed to parse grpc_service %v\", err)\n\t}\n\n\tmutationRules, err := httpfilter.HeaderMutationRulesFromProto(msg.GetMutationRules())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/extproc/ext_proc.go#L101-L137","documentation":"Raised by ParseFilterConfig (ext_proc.go:119) when the ExternalProcessor config unmarshals successfully but its processing_mode field is nil. ext_proc requires a processing_mode to decide which headers/bodies/trailers to forward; an absent one is rejected before validateBodyProcessingMode even runs.","triggerScenarios":"msg.GetProcessingMode() == nil at ext_proc.go:118 — the ExternalProcessor proto was provided but the processing_mode sub-message was left unset.","commonSituations":"A minimal ext_proc config that only sets grpc_service and omits processing_mode, assuming defaults; a control-plane template whose processing_mode block is conditionally empty; porting an Envoy config that relies on Envoy's implicit defaults (gRPC requires explicit processing_mode here).","solutions":["Add an explicit processing_mode block to the ExternalProcessor config.","At minimum set the header/body modes you need using only NONE/GRPC (and SEND for response trailers when response body is GRPC).","If you want all-skip behavior, still provide processing_mode with the relevant fields set to NONE/SKIP."],"exampleFix":"// before\n//   external_processor: { grpc_service: { ... } }   // processing_mode omitted -> error 377\n//\n// after\n//   external_processor: {\n//     grpc_service: { google_grpc: { target_uri: \"proc:9092\" } },\n//     processing_mode: { request_header_mode: SEND, request_body_mode: NONE,\n//                        response_header_mode: SEND, response_body_mode: NONE }\n//   }","handlingStrategy":"validation","validationCode":"// Ensure processing_mode is present (ext_proc.go:118-120).\nfunc ensureProcessingMode(cfg *v3procfilterpb.ExternalProcessor) error {\n    if cfg.GetProcessingMode() == nil {\n        return fmt.Errorf(\"extproc: processing_mode is required\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include an explicit processing_mode in ext_proc configs — gRPC does not assume Envoy's defaults.","Make processing_mode a required field in your control-plane schema/template.","Lint ext_proc resources for a missing processing_mode in CI."],"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"}