{"record":{"id":"877f305d9b5928fc","repo":"grpc/grpc-go","slug":"fault-error-parsing-config-v-v","errorCode":null,"errorMessage":"fault: error parsing config %v: %v","messagePattern":"fault: error parsing config (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/fault/fault.go","lineNumber":91,"sourceCode":"\tconfig *fpb.HTTPFault\n}\n\nfunc (builder) TypeURLs() []string {\n\treturn []string{\"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault\"}\n}\n\n// Parsing is the same for the base config and the override config.\nfunc parseConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\tif cfg == nil {\n\t\treturn nil, fmt.Errorf(\"fault: nil configuration message provided\")\n\t}\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"fault: error parsing config %v: unknown type %T\", cfg, cfg)\n\t}\n\tmsg := new(fpb.HTTPFault)\n\tif err := m.UnmarshalTo(msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"fault: error parsing config %v: %v\", cfg, err)\n\t}\n\treturn config{config: msg}, nil\n}\n\nfunc (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\treturn parseConfig(cfg)\n}\n\nfunc (builder) ParseFilterConfigOverride(override proto.Message) (httpfilter.FilterConfig, error) {\n\treturn parseConfig(override)\n}\n\nfunc (builder) IsTerminal() bool {\n\treturn false\n}\n\nfunc (builder) BuildClientFilter(httpfilter.ClientFilterOptions) httpfilter.ClientFilter {\n\treturn clientFilter{}","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/fault/fault.go#L73-L109","documentation":"parseConfig (fault.go:90) successfully type-asserted *anypb.Any but UnmarshalTo into fpb.HTTPFault failed. Causes: the Any's type_url does not match HTTPFault, the serialized bytes are corrupt, or the wire schema differs from the linked proto version.","triggerScenarios":"anypb.Any with a mismatched type URL (e.g., a different filter's URL), truncated/malformed payload, or version skew where the server's HTTPFault schema differs from the client's compiled proto.","commonSituations":"Control-plane and data-plane built from different Envoy proto versions; corrupted config in transit; wrong filter config bound to the fault TypeURL.","solutions":["Ensure the anypb.Any type_url is exactly type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault.","Pin the go-control-plane dependency version to match between server and client.","Log the wrapped error to identify whether it is a type-URL mismatch or a wire-format decode error."],"exampleFix":"// before\nanyCfg := &anypb.Any{TypeUrl: \"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFaultLegacy\", Value: raw}\n\n// after\nanyCfg := &anypb.Any{TypeUrl: \"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault\", Value: raw}","handlingStrategy":"validation","validationCode":"if m, ok := cfg.(*anypb.Any); ok {\n    want := \"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault\"\n    if m.TypeUrl != want {\n        return nil, fmt.Errorf(\"fault: type_url %q != %q\", m.TypeUrl, want)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"error parsing config\") {\n    // inspect the wrapped error to distinguish type-URL mismatch from wire corruption\n}","preventionTips":["Pin go-control-plane versions across control-plane and data-plane.","Validate the Any.TypeUrl against builder.TypeURLs() before unmarshalling.","Add a conformance test that round-trips an HTTPFault through ParseFilterConfig."],"tags":["fault","config","protobuf","xds","grpc"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}