{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/fault/fault.go#L73-L109","documentation":"After confirming the config is an *anypb.Any, parseConfig unmarshals it into envoy.extensions.filters.http.fault.v3.HTTPFault (fault.go:90). If UnmarshalTo fails, the payload is malformed, has the wrong type URL, or is corrupt.","triggerScenarios":"The Any payload does not deserialize as HTTPFault: wrong type URL, truncated bytes, schema-incompatible content, or a proto version mismatch.","commonSituations":"xDS server sends a fault config generated by an incompatible protobuf; hand-crafted Any with the wrong type URL; network/serialization corruption; using an old control plane with a new go-control-plane.","solutions":["Validate the Any.TypeURL equals type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault before decoding.","Regenerate the fault config from a control plane whose protobuf definitions match the client's go-control-plane version.","Inspect the raw bytes/size of the failing Any to detect truncation or corruption."],"exampleFix":"// before: Any with mismatched type URL or corrupt bytes\nanyMsg := &anypb.Any{TypeUrl: \"type.googleapis.com/wrong.Type\", Value: corruptBytes}\n\n// after: correct type URL and a validly-marshaled HTTPFault\nanyMsg, _ := anypb.New(&fpb.HTTPFault{Abort: &fpb.FaultAbort{HttpStatus: &corev3.HttpStatus{Code: corev3.StatusCode_GatewayError}}})","handlingStrategy":"validation","validationCode":"if cfg.(*anypb.Any).TypeUrl != \"type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault\" {\n    return nil, errors.New(\"wrong type URL for fault config\")\n}","typeGuard":null,"tryCatchPattern":"fc, err := faultBuilder.ParseFilterConfig(cfg)\nif err != nil {\n    // log type URL + byte length to diagnose corruption\n    return err\n}","preventionTips":["Pin go-control-plane and control-plane protobuf versions together.","Validate TypeURL before decoding filter configs.","Log Any size on unmarshal failure to catch truncation."],"tags":["fault-injection","grpc","xds","config","serialization","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}