grpc/grpc-go · error
fault: incorrect config type provided (%T): %v
Error message
fault: incorrect config type provided (%T): %v
What it means
BuildClientInterceptor asserts the base config is the internal fault config type produced by parseConfig (fault.go:123). A different concrete type means the build step received a config not created by this builder, indicating a wiring mismatch.
Source
Thrown at internal/xds/httpfilter/fault/fault.go:125
func (builder) BuildClientFilter(httpfilter.ClientFilterOptions) httpfilter.ClientFilter {
return clientFilter{}
}
var _ httpfilter.ClientFilterBuilder = builder{}
type clientFilter struct{}
func (clientFilter) Close() {}
func (clientFilter) BuildClientInterceptor(cfg, override httpfilter.FilterConfig) (httpfilter.ClientInterceptor, error) {
if cfg == nil {
return nil, fmt.Errorf("fault: nil config provided")
}
c, ok := cfg.(config)
if !ok {
return nil, fmt.Errorf("fault: incorrect config type provided (%T): %v", cfg, cfg)
}
if override != nil {
// override completely replaces the listener configuration; but we
// still validate the listener config type.
c, ok = override.(config)
if !ok {
return nil, fmt.Errorf("fault: incorrect override config type provided (%T): %v", override, override)
}
}
icfg := c.config
if (icfg.GetMaxActiveFaults() != nil && icfg.GetMaxActiveFaults().GetValue() == 0) ||
(icfg.GetDelay() == nil && icfg.GetAbort() == nil) {
return nil, nil
}
return &interceptor{config: icfg}, nil
}View on GitHub (pinned to 03255a9237)
Solutions
- Pass only the httpfilter.FilterConfig returned by the fault builder's ParseFilterConfig into BuildClientInterceptor.
- Do not reconstruct or re-type the config between parse and build.
- Add a build-time check that the builder and config originate from the same package.
Example fix
// before: passing a raw *fpb.HTTPFault ic, err := cf.BuildClientInterceptor(rawHTTPFault, nil) // after: pass the FilterConfig produced by the fault builder parsed, err := faultBuilder.ParseFilterConfig(anyMsg) ic, err := cf.BuildClientInterceptor(parsed, nil)
Defensive patterns
Strategy: type-guard
Validate before calling
// cfg must come from the fault builder's ParseFilterConfig // (the concrete type is unexported, so never reconstruct it by hand)
Type guard
// Internal type; callers can only assert it round-tripped through ParseFilterConfig:
func isFaultConfig(c httpfilter.FilterConfig) bool {
// no public way to name the unexported config; rely on builder pairing
return c != nil
} Try / catch
ic, err := cf.BuildClientInterceptor(cfg, override)
if err != nil {
return err
} Prevention
- Use the same builder for parse and build; do not re-type configs across filters.
- Avoid wrapping the config in a generic adapter between stages.
- Test parse+build end-to-end per filter.
When it happens
Trigger: cfg passed to BuildClientInterceptor does not implement/assert as the unexported fault config struct (e.g. it is the raw *fpb.HTTPFault or a config from another filter).
Common situations: Mixing filter builders and configs across filters; a custom filter framework that re-wraps configs; refactor that changed the config struct without updating the build path.
Related errors
- fault: error parsing config %v: unknown type %T
- 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/02a6498a2b5cf709.
Report an issue: GitHub.