diff --git a/pkg/controller/podautoscaler/replica_calculator.go b/pkg/controller/podautoscaler/replica_calculator.go index 49f68ae0c4e..00ae980d47a 100644 --- a/pkg/controller/podautoscaler/replica_calculator.go +++ b/pkg/controller/podautoscaler/replica_calculator.go @@ -360,8 +360,14 @@ func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, tar if err != nil { return 0, 0, time.Time{}, fmt.Errorf("unable to get external metric %s/%s/%+v: %s", namespace, metricName, metricSelector, err) } + usage = 0 for _, val := range metrics { + // Cap at MaxInt64 for positive overflow + if val > 0 && usage > math.MaxInt64-val { + usage = math.MaxInt64 + break + } usage = usage + val } diff --git a/pkg/controller/podautoscaler/replica_calculator_test.go b/pkg/controller/podautoscaler/replica_calculator_test.go index 202bce959d4..bd8755fb56c 100644 --- a/pkg/controller/podautoscaler/replica_calculator_test.go +++ b/pkg/controller/podautoscaler/replica_calculator_test.go @@ -2477,3 +2477,21 @@ func TestCalculatePodRequestsFromContainers_NonExistentContainer(t *testing.T) { assert.Equal(t, expectedErr, err.Error(), "error message should match expected format") assert.Equal(t, int64(0), request, "request should be 0 when container does not exist") } + +func TestReplicaCalcExternalMetricUsageOverflow(t *testing.T) { + tc := replicaCalcTestCase{ + currentReplicas: 3, + expectedReplicas: 3, + metric: &metricInfo{ + name: "qps", + // Two values that when added together will overflow int64 + levels: []int64{math.MaxInt64/2 + 1, math.MaxInt64/2 + 1}, + targetUsage: math.MaxInt64, // Set high target + metricType: externalMetric, + selector: &metav1.LabelSelector{MatchLabels: map[string]string{"label": "value"}}, + expectedUsage: math.MaxInt64, // expect capped value + + }, + } + tc.runTest(t) +}