{"record":{"id":"47cfcbc30f05c061","repo":"grpc/grpc-go","slug":"outlierdetectionloadbalancingconfig-successrateeje","errorCode":null,"errorMessage":"OutlierDetectionLoadBalancingConfig.SuccessRateEjection.enforcement_percentage = %v; must be <= 100","messagePattern":"OutlierDetectionLoadBalancingConfig\\.SuccessRateEjection\\.enforcement_percentage = (.+?); must be <= 100","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/outlierdetection/balancer.go","lineNumber":145,"sourceCode":"\t// Approximately 290 years is the maximum time that time.Duration (int64)\n\t// can represent. The restrictions on the protobuf.Duration field are to be\n\t// within +-10000 years. Thus, just check for negative values.\n\tcase lbCfg.Interval < 0:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.interval = %s; must be >= 0\", lbCfg.Interval)\n\tcase lbCfg.BaseEjectionTime < 0:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.base_ejection_time = %s; must be >= 0\", lbCfg.BaseEjectionTime)\n\tcase lbCfg.MaxEjectionTime < 0:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.max_ejection_time = %s; must be >= 0\", lbCfg.MaxEjectionTime)\n\n\t// \"The fields max_ejection_percent,\n\t// success_rate_ejection.enforcement_percentage,\n\t// failure_percentage_ejection.threshold, and\n\t// failure_percentage.enforcement_percentage must have values less than or\n\t// equal to 100.\" - A50\n\tcase lbCfg.MaxEjectionPercent > 100:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.max_ejection_percent = %v; must be <= 100\", lbCfg.MaxEjectionPercent)\n\tcase lbCfg.SuccessRateEjection != nil && lbCfg.SuccessRateEjection.EnforcementPercentage > 100:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.SuccessRateEjection.enforcement_percentage = %v; must be <= 100\", lbCfg.SuccessRateEjection.EnforcementPercentage)\n\tcase lbCfg.FailurePercentageEjection != nil && lbCfg.FailurePercentageEjection.Threshold > 100:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.FailurePercentageEjection.threshold = %v; must be <= 100\", lbCfg.FailurePercentageEjection.Threshold)\n\tcase lbCfg.FailurePercentageEjection != nil && lbCfg.FailurePercentageEjection.EnforcementPercentage > 100:\n\t\treturn nil, fmt.Errorf(\"OutlierDetectionLoadBalancingConfig.FailurePercentageEjection.enforcement_percentage = %v; must be <= 100\", lbCfg.FailurePercentageEjection.EnforcementPercentage)\n\t}\n\treturn lbCfg, nil\n}\n\nfunc (bb) Name() string {\n\treturn Name\n}\n\n// scUpdate wraps a subConn update to be sent to the child balancer.\ntype scUpdate struct {\n\tscw   *subConnWrapper\n\tstate balancer.SubConnState\n}\n","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/balancer/outlierdetection/balancer.go#L127-L163","documentation":"Returned by outlier detection ParseConfig (internal/xds/balancer/outlierdetection/balancer.go:144) when the optional `success_rate_ejection` block is present and its `enforcement_percentage` exceeds 100. gRFC A50 caps this field at 100; it controls the probability that a detected outlier is actually ejected.","triggerScenarios":"ParseConfig gets JSON containing a `successRateEjection` object whose `enforcementPercentage` is > 100. Only checked when the success_rate_ejection block is non-nil.","commonSituations":"Control plane emits enforcement_percentage as a fraction (e.g. 1000 meaning 100%) instead of a 0-100 integer; misconfigured outlier detection policy.","solutions":["Set `successRateEjection.enforcementPercentage` to 0-100 (omit the block to disable success-rate ejection)","Correct the upstream OutlierDetection success_rate_ejection config","Validate percentage fields against the 0-100 range before publishing"],"exampleFix":"// before\n{\"successRateEjection\":{\"enforcementPercentage\":150}}\n// after\n{\"successRateEjection\":{\"enforcementPercentage\":100}}","handlingStrategy":"validation","validationCode":"var probe struct{ SRE struct{ EnforcementPercentage uint32 `json:\"enforcement_percentage\"` } `json:\"success_rate_ejection\"` }\n_ = json.Unmarshal(raw, &probe)\nif probe.SRE.EnforcementPercentage > 100 {\n    return fmt.Errorf(\"success_rate enforcement_percentage must be <= 100, got %d\", probe.SRE.EnforcementPercentage)\n}","typeGuard":null,"tryCatchPattern":"lbCfg, err := outlierBB.ParseConfig(raw)\nif err != nil {\n    logger.Warningf(\"rejecting outlier detection config: %v\", err)\n    return fallbackLBConfig\n}","preventionTips":["Remember enforcement_percentage is 0-100, not a fraction","Validate only when the success_rate_ejection block is present"],"tags":["grpc","xds","outlier-detection","load-balancing","config","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}