{"record":{"id":"b7495d130a375bc2","repo":"grpc/grpc-go","slug":"extproc-failed-to-unmarshal-config-v-v","errorCode":null,"errorMessage":"extproc: failed to unmarshal config %v: %v","messagePattern":"extproc: failed to unmarshal config (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/extproc/ext_proc.go","lineNumber":116,"sourceCode":"\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)\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 {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/extproc/ext_proc.go#L98-L134","documentation":"Raised by ParseFilterConfig (ext_proc.go:116) when the ExternalProcessor Any's bytes cannot be deserialized into envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor. The ext_proc counterpart to error 360: structurally invalid wire data for the declared type causes the LDS resource to be NACKed.","triggerScenarios":"cfg is a valid *anypb.Any but m.UnmarshalTo(new(v3procfilterpb.ExternalProcessor)) at ext_proc.go:115 returns a non-nil error — corrupt/truncated bytes, or payload serialized from a different message than the type_url claims.","commonSituations":"Control plane emitted a malformed ExternalProcessor config; type_url says ExternalProcessor but the body is a different proto; v2/v3 or go-control-plane version mismatch.","solutions":["Read the wrapped %v for the protobuf-level cause (unexpected EOF = truncation; unknown field = version skew).","Confirm type_url is 'type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor' and the body decodes as that exact message.","Decode Any.value with protoc against the v3 ExternalProcessor descriptor; re-emit a correct resource."],"exampleFix":"// before: Any payload is not a valid ExternalProcessor\n//\n// after: marshal the real v3 ExternalProcessor into the Any\nimport (\n  \"google.golang.org/protobuf/types/known/anypb\"\n  v3procfilterpb \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_proc/v3\"\n)\nep := &v3procfilterpb.ExternalProcessor{\n  GrpcService:    &v3corepb.GrpcService{ /* google_grpc... */ },\n  ProcessingMode: &v3procfilterpb.ProcessingMode{ /* NONE/GRPC only */ },\n}\nanyCfg, err := anypb.New(ep)","handlingStrategy":"validation","validationCode":"// Validate an ExternalProcessor Any before publishing (ext_proc.go:114-116).\nfunc validateExtProcAny(a *anypb.Any) error {\n    if a == nil || a.TypeUrl != \"type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor\" {\n        return fmt.Errorf(\"wrong/nil type_url for ExternalProcessor\")\n    }\n    msg := new(v3procfilterpb.ExternalProcessor)\n    if err := a.UnmarshalTo(msg); err != nil {\n        return fmt.Errorf(\"ExternalProcessor payload invalid: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build ext_proc configs with anypb.New so type_url and payload agree.","Match go-control-plane/envoy proto versions between control plane and client.","Decode Any.value with protoc in CI before publishing."],"tags":["grpc","xds","protobuf","config","ext-proc"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}