{"record":{"id":"2914ad1d23f3a15b","repo":"grpc/grpc-go","slug":"error-parsing-outlier-detection-config-v-v","errorCode":null,"errorMessage":"error parsing Outlier Detection config %v: %v","messagePattern":"error parsing Outlier Detection config (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/cdsbalancer/cdsbalancer.go","lineNumber":357,"sourceCode":"\t\treturn fmt.Errorf(\"%q LB policy is needed but not registered\", outlierdetection.Name)\n\t}\n\n\todParser, ok := odBuilder.(balancer.ConfigParser)\n\tif !ok {\n\t\t// Shouldn't happen, imported Outlier Detection builder has this method.\n\t\treturn fmt.Errorf(\"%q LB policy does not implement a config parser\", outlierdetection.Name)\n\t}\n\n\tfor _, p := range b.priorities {\n\t\t// Update Outlier Detection Config.\n\t\todJSON := p.clusterConfig.Cluster.OutlierDetection\n\t\tif odJSON == nil {\n\t\t\todJSON = json.RawMessage(`{}`)\n\t\t}\n\n\t\tlbCfg, err := odParser.ParseConfig(odJSON)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing Outlier Detection config %v: %v\", odJSON, err)\n\t\t}\n\n\t\todCfg, ok := lbCfg.(*outlierdetection.LBConfig)\n\t\tif !ok {\n\t\t\t// Shouldn't happen, Parser built at build time with Outlier\n\t\t\t// Detection builder pulled from gRPC LB Registry.\n\t\t\treturn fmt.Errorf(\"config parser for Outlier Detection returned config with unexpected type %T: %v\", lbCfg, lbCfg)\n\t\t}\n\t\tp.outlierDetection = *odCfg\n\t}\n\treturn nil\n}\n\n// ResolverError handles errors reported by the xdsResolver.\nfunc (b *cdsBalancer) ResolverError(err error) {\n\t// Missing Listener or RouteConfiguration on the management server\n\t// results in a 'resource not found' error from the xDS resolver. In\n\t// these cases, we should report transient failure.","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/balancer/cdsbalancer/cdsbalancer.go#L339-L375","documentation":"The CDS balancer parses the Outlier Detection JSON from each cluster resource using the outlier detection balancer's config parser. This error fires when that JSON fails to parse, including validation failures for negative durations, invalid ejection percentages, or malformed child config. The Outlier Detection JSON comes from the management server's cluster resource.","triggerScenarios":"Triggered in updateOutlierDetection() when odParser.ParseConfig(odJSON) returns an error for one of the priorities. The odJSON bytes are the raw OutlierDetection field from the cluster resource; if nil, a default empty config {} is used. The parser validates interval, base_ejection_time, max_ejection_time (non-negative), max_ejection_percent (0-100), and child config validity.","commonSituations":"The management server sends outlier detection config with negative duration values, ejection percentages > 100, or missing required sub-config fields; a malformed protobuf-to-JSON conversion on the server side; the SRE (Success Rate Ejection) or FPE (Failure Percentage Ejection) sub-configs have invalid values.","solutions":["Inspect the raw Outlier Detection JSON from the management server for the failing cluster (enable xDS logging)","Verify all duration fields (interval, base_ejection_time, max_ejection_time) are non-negative","Verify max_ejection_percent is between 0 and 100","Check that SRE and FPE sub-configs (if present) have valid numeric thresholds","Disable outlier detection for the cluster on the management server if the config cannot be fixed immediately"],"exampleFix":"// before: negative interval in outlier detection config\n{\"interval\": \"-5s\", \"baseEjectionTime\": \"30s\"}\n// after: non-negative durations\n{\"interval\": \"10s\", \"baseEjectionTime\": \"30s\"}","handlingStrategy":"validation","validationCode":"// Validate outlier detection JSON before relying on it\nfunc validateOutlierDetectionJSON(raw json.RawMessage) error {\n    var cfg struct {\n        Interval           *string  `json:\"interval\"`\n        BaseEjectionTime   *string  `json:\"baseEjectionTime\"`\n        MaxEjectionTime    *string  `json:\"maxEjectionTime\"`\n        MaxEjectionPercent *float64 `json:\"maxEjectionPercent\"`\n    }\n    if err := json.Unmarshal(raw, &cfg); err != nil {\n        return err\n    }\n    // Validate durations are non-negative and percent is 0-100\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate management server outlier detection configs for valid durations and percentages","Ensure all duration fields are non-negative strings in Go duration format","Keep max_ejection_percent between 0 and 100","Test outlier detection configs in staging before production"],"tags":["xds","cds","outlier-detection","json","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}