grpc/grpc-go · error
fault: error parsing config %v: unknown type %T
Error message
fault: error parsing config %v: unknown type %T
What it means
parseConfig expects the incoming proto.Message to be an *anypb.Any (fault.go:85). Any other concrete type indicates the xDS decoding pipeline passed the wrong message type to the fault builder, which is a programmer/decoder contract violation.
Source
Thrown at internal/xds/httpfilter/fault/fault.go:87
}
type config struct {
httpfilter.FilterConfig
config *fpb.HTTPFault
}
func (builder) TypeURLs() []string {
return []string{"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault"}
}
// Parsing is the same for the base config and the override config.
func parseConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
if cfg == nil {
return nil, fmt.Errorf("fault: nil configuration message provided")
}
m, ok := cfg.(*anypb.Any)
if !ok {
return nil, fmt.Errorf("fault: error parsing config %v: unknown type %T", cfg, cfg)
}
msg := new(fpb.HTTPFault)
if err := m.UnmarshalTo(msg); err != nil {
return nil, fmt.Errorf("fault: error parsing config %v: %v", cfg, err)
}
return config{config: msg}, nil
}
func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {
return parseConfig(cfg)
}
func (builder) ParseFilterConfigOverride(override proto.Message) (httpfilter.FilterConfig, error) {
return parseConfig(override)
}
func (builder) IsTerminal() bool {
return falseView on GitHub (pinned to 03255a9237)
Solutions
- Always pass an *anypb.Any whose TypeURL is type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault.
- Fix the resource decoder so it does not pre-unmarshal the filter config before the builder sees it.
- Confirm the TypeURLs() of the fault builder match the resource type being routed to it.
Example fix
// before: passing the concrete HTTPFault directly
fc, err := faultBuilder.ParseFilterConfig(&fpb.HTTPFault{})
// after: wrap in *anypb.Any
anyMsg, _ := anypb.New(&fpb.HTTPFault{})
fc, err := faultBuilder.ParseFilterConfig(anyMsg) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := cfg.(*anypb.Any); !ok {
return nil, fmt.Errorf("expected *anypb.Any, got %T", cfg)
}
fc, err := faultBuilder.ParseFilterConfig(cfg) Type guard
func isAnyMsg(m proto.Message) bool {
_, ok := m.(*anypb.Any)
return ok
} Prevention
- Always hand *anypb.Any to filter builders, not pre-unwrapped messages.
- Keep the decoder and builder types aligned via shared TypeURL constants.
- Add a type assertion in the decoder before dispatching to builders.
When it happens
Trigger: ParseFilterConfig receives a proto.Message that is not *anypb.Any (e.g. the already-unwrapped *fpb.HTTPFault or a raw struct message).
Common situations: A custom xdsclient/resource-decoder that pre-unwraps the Any before handing it to the filter builder; test harness passing the concrete type; type-url routing mismatch causing the wrong builder to handle the message.
Related errors
- fault: incorrect config type provided (%T): %v
- fault: incorrect override config type provided (%T): %v
- fault: nil configuration message provided
- fault: error parsing config %v: %v
- fault: nil config provided
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/69ff11dd68512ea6.
Report an issue: GitHub.