grpc/grpc-go · error
extproc: failed to unmarshal config
Error message
extproc: failed to unmarshal config %v: %v
What it means
Returned by ParseFilterConfig when anypb.Any.UnmarshalTo fails to decode the packed bytes into an ExternalProcessor message. Usually the type_url does not match ExternalProcessor's full name, the bytes are corrupted, or the proto schema versions between control plane and client are incompatible. Hit at ext_proc.go:115.
Solutions
- Verify the Any.type_url matches the builder's advertised TypeURL (see TypeURLs() in ext_proc.go:86).
- Align the go-control-plane version between the control plane and grpc-go client.
- Re-serialize the resource from a known-good ExternalProcessor message.
- Check the server logs / xDS dump (e.g. via xds-resolver debugging) for the raw bytes and validate them standalone.
Example fix
// control plane - before
any, _ := anypb.New(otherFilterMsg)
// after: ensure correct type and version
any, _ := anypb.New(&v3extproc.ExternalProcessor{...})
// confirm any.TypeUrl == "type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor" Defensive patterns
Strategy: validation
Validate before calling
// verify type URL and decodability before sending
want := "type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor"
if any.TypeUrl != want { return fmt.Errorf("wrong type_url %q", any.TypeUrl) }
probe := new(v3extproc.ExternalProcessor)
if err := any.UnmarshalTo(probe); err != nil { return err } Prevention
- Match go-control-plane versions between control plane and client.
- Verify the Any.type_url equals the builder's TypeURL.
- Re-serialize resources from known-good messages.
- Use the xDS debug dump to inspect raw bytes.
When it happens
Trigger: The xDS resource delivers an *anypb.Any whose type_url is not type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor, or whose value bytes are malformed / from a newer proto revision with unknown fields that UnmarshalTo rejects.
Common situations: Control plane and grpc-go use different versions of go-control-plane with incompatible ext_proc protos; type URL typo in the control plane; resource corrupted in transit or by a buggy serializer; wrong filter is wired to the ext_proc type URL.
Related errors
- extproc: failed to unmarshal override
- external processor sent an immediate response but immediate…
- extproc: empty grpc_service provided in config
- extproc: error parsing config
- extproc: error parsing override
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/b7495d130a375bc2.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/httpfilter/extproc/ext_proc.go:116
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)
}
if msg.GetProcessingMode() == nil {
return nil, fmt.Errorf("extproc: missing processing_mode in config %v", cfg)
}
if err := validateBodyProcessingMode(msg.GetProcessingMode()); err != nil {
return nil, err
}
if msg.GetGrpcService() == nil {
return nil, fmt.Errorf("extproc: empty grpc_service provided in config %v", cfg)
}
server, err := iextproc.ParseGRPCServiceConfig(msg.GetGrpcService())
if err != nil {
return nil, fmt.Errorf("extproc: failed to parse grpc_service %v", err)
}
mutationRules, err := httpfilter.HeaderMutationRulesFromProto(msg.GetMutationRules())
if err != nil {View on GitHub (pinned to 0c51461d27)