grpc/grpc-go · error

fault: error parsing config

Error message

fault: error parsing config %v: unknown type %T

What it means

parseConfig (fault.go:85) requires the cfg to be *anypb.Any. The type assertion fails for any other concrete proto.Message type (e.g., passing the *fpb.HTTPFault directly instead of wrapping it).

Solutions

  1. Wrap the HTTPFault proto in an anypb.Any using anypb.New before passing it in.
  2. Verify the type URL matches type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault.
  3. Use the builder's TypeURLs() list as the source of truth for acceptable URLs.

Example fix

// before
cfg, err := faultBuilder.ParseFilterConfig(&fpb.HTTPFault{...})

// after
anyCfg, err := anypb.New(&fpb.HTTPFault{...})
cfg, err := faultBuilder.ParseFilterConfig(anyCfg)
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := cfg.(*anypb.Any); !ok {
    return nil, fmt.Errorf("fault: expected *anypb.Any, got %T", cfg)
}

Type guard

func isAnyPB(m proto.Message) bool { _, ok := m.(*anypb.Any); return ok }

Try / catch

if _, ok := cfg.(*anypb.Any); !ok {
    anyCfg, err := anypb.New(cfg)
    if err != nil { return err }
    cfg = anyCfg
}
fc, err := faultBuilder.ParseFilterConfig(cfg)

Prevention

When it happens

Trigger: ParseFilterConfig is called with a proto.Message that is not *anypb.Any — most commonly a *fpb.HTTPFault, *fpb.HTTPFault pointer, or a different filter's config proto.

Common situations: Programmatic test/registration that passes the unwrapped filter proto; cross-wiring configs between filters; control-plane bug that sends the raw proto instead of an Any.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/69ff11dd68512ea6. Report an issue: GitHub.

Appendix: 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 false

View on GitHub (pinned to 0c51461d27)