{"record":{"id":"5e24bb381877d1e8","repo":"grpc/grpc-go","slug":"fault-incorrect-override-config-type-provided-t","errorCode":null,"errorMessage":"fault: incorrect override config type provided (%T): %v","messagePattern":"fault: incorrect override config type provided \\(%T\\): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/fault/fault.go","lineNumber":133,"sourceCode":"\nfunc (clientFilter) Close() {}\n\nfunc (clientFilter) BuildClientInterceptor(cfg, override httpfilter.FilterConfig) (httpfilter.ClientInterceptor, error) {\n\tif cfg == nil {\n\t\treturn nil, fmt.Errorf(\"fault: nil config provided\")\n\t}\n\n\tc, ok := cfg.(config)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"fault: incorrect config type provided (%T): %v\", cfg, cfg)\n\t}\n\n\tif override != nil {\n\t\t// override completely replaces the listener configuration; but we\n\t\t// still validate the listener config type.\n\t\tc, ok = override.(config)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"fault: incorrect override config type provided (%T): %v\", override, override)\n\t\t}\n\t}\n\n\ticfg := c.config\n\tif (icfg.GetMaxActiveFaults() != nil && icfg.GetMaxActiveFaults().GetValue() == 0) ||\n\t\t(icfg.GetDelay() == nil && icfg.GetAbort() == nil) {\n\t\treturn nil, nil\n\t}\n\treturn &interceptor{config: icfg}, nil\n}\n\ntype interceptor struct {\n\tconfig *fpb.HTTPFault\n}\n\nvar activeFaults uint32 // global active faults; accessed atomically\n\nfunc (i *interceptor) NewStream(ctx context.Context, _ iresolver.RPCInfo, newStream func(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStream, error), opts ...grpc.CallOption) (grpc.ClientStream, error) {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/fault/fault.go#L115-L151","documentation":"BuildClientInterceptor (fault.go:132) applies the same type check to the override config when it is non-nil. The override must also be the fault filter's internal config type; otherwise the assertion fails.","triggerScenarios":"BuildClientInterceptor is called with a non-nil override that is not the fault filter's internal config struct (e.g., an override parsed by a different builder, or a raw *fpb.HTTPFault).","commonSituations":"Override config parsed by the wrong builder; control-plane sending a per-route override with the wrong typed config; refactor that swapped builders.","solutions":["Parse the override with the fault builder's ParseFilterConfigOverride before passing it.","Ensure the per-route override in the xDS Route uses the fault TypeURL.","Do not pass overrides produced by other filter builders."],"exampleFix":"// before\nic, err := faultCF.BuildClientInterceptor(cfg, otherBuilderOverride)\n\n// after\noverride, err := faultBuilder.ParseFilterConfigOverride(anyOverride)\nic, err := faultCF.BuildClientInterceptor(cfg, override)","handlingStrategy":"type-guard","validationCode":"if override != nil {\n    // Ensure override came from the same fault builder's ParseFilterConfigOverride.\n    if _, ok := override.(httpfilter.FilterConfig); !ok { /* still wrong type internally */ }\n}","typeGuard":null,"tryCatchPattern":"ic, err := cf.BuildClientInterceptor(cfg, override)\nif err != nil && strings.Contains(err.Error(), \"incorrect override config type\") {\n    override, oerr := faultBuilder.ParseFilterConfigOverride(anyOverride)\n    if oerr != nil { return oerr }\n    ic, err = cf.BuildClientInterceptor(cfg, override)\n}","preventionTips":["Parse overrides with the same builder that parses the base config.","Bind per-route overrides in xDS using the fault TypeURL only."],"tags":["fault","config","type","grpc","xds"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}