grpc/grpc-go · error

OutlierDetectionLoadBalancingConfig.FailurePercentageEjectio

Error message

OutlierDetectionLoadBalancingConfig.FailurePercentageEjection.enforcement_percentage = %v; must be <= 100

What it means

Returned by outlier detection ParseConfig (internal/xds/balancer/outlierdetection/balancer.go:148) when the optional `failure_percentage_ejection` block is present and its `enforcement_percentage` exceeds 100. gRFC A50 caps this field at 100; it controls the probability a failure-percentage outlier is actually ejected.

Source

Thrown at internal/xds/balancer/outlierdetection/balancer.go:149

		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.interval = %s; must be >= 0", lbCfg.Interval)
	case lbCfg.BaseEjectionTime < 0:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.base_ejection_time = %s; must be >= 0", lbCfg.BaseEjectionTime)
	case lbCfg.MaxEjectionTime < 0:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.max_ejection_time = %s; must be >= 0", lbCfg.MaxEjectionTime)

	// "The fields max_ejection_percent,
	// success_rate_ejection.enforcement_percentage,
	// failure_percentage_ejection.threshold, and
	// failure_percentage.enforcement_percentage must have values less than or
	// equal to 100." - A50
	case lbCfg.MaxEjectionPercent > 100:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.max_ejection_percent = %v; must be <= 100", lbCfg.MaxEjectionPercent)
	case lbCfg.SuccessRateEjection != nil && lbCfg.SuccessRateEjection.EnforcementPercentage > 100:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.SuccessRateEjection.enforcement_percentage = %v; must be <= 100", lbCfg.SuccessRateEjection.EnforcementPercentage)
	case lbCfg.FailurePercentageEjection != nil && lbCfg.FailurePercentageEjection.Threshold > 100:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.FailurePercentageEjection.threshold = %v; must be <= 100", lbCfg.FailurePercentageEjection.Threshold)
	case lbCfg.FailurePercentageEjection != nil && lbCfg.FailurePercentageEjection.EnforcementPercentage > 100:
		return nil, fmt.Errorf("OutlierDetectionLoadBalancingConfig.FailurePercentageEjection.enforcement_percentage = %v; must be <= 100", lbCfg.FailurePercentageEjection.EnforcementPercentage)
	}
	return lbCfg, nil
}

func (bb) Name() string {
	return Name
}

// scUpdate wraps a subConn update to be sent to the child balancer.
type scUpdate struct {
	scw   *subConnWrapper
	state balancer.SubConnState
}

type ejectionUpdate struct {
	scw       *subConnWrapper
	isEjected bool // true for ejected, false for unejected
}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Set `failurePercentageEjection.enforcementPercentage` to 0-100 (omit the block to disable)
  2. Correct the upstream OutlierDetection failure_percentage_ejection config
  3. Range-check enforcement percentages before publishing

Example fix

// before
{"failurePercentageEjection":{"enforcementPercentage":200}}
// after
{"failurePercentageEjection":{"enforcementPercentage":100}}
Defensive patterns

Strategy: validation

Validate before calling

var probe struct{ FPE struct{ EnforcementPercentage uint32 `json:"enforcement_percentage"` } `json:"failure_percentage_ejection"` }
_ = json.Unmarshal(raw, &probe)
if probe.FPE.EnforcementPercentage > 100 {
    return fmt.Errorf("failure_percentage enforcement_percentage must be <= 100, got %d", probe.FPE.EnforcementPercentage)
}

Try / catch

lbCfg, err := outlierBB.ParseConfig(raw)
if err != nil {
    logger.Warningf("rejecting outlier detection config: %v", err)
    return fallbackLBConfig
}

Prevention

When it happens

Trigger: ParseConfig gets JSON with a `failurePercentageEjection` object whose `enforcementPercentage` is > 100. Only checked when the block is non-nil.

Common situations: Control plane emits the value on a 0-1000 scale; operator confusion about percent vs fraction; misconfigured policy.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/8ebedf7bc970bfff. Report an issue: GitHub.