Report
I am unable to get my ScaledObject to scale my HPA to 0.
Metrics: ( current / target )
"s0-forgejo" (target average value): 0 / 1
{
"level": "debug",
"ts": "2026-03-08T11:54:57Z",
"logger": "scale_handler",
"msg": "Getting metrics and activity from scaler",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"scaler": "trig_one",
"metricName": "s0-forgejo",
"metrics": [
{
"metricName": "s0-forgejo",
"metricLabels": null,
"timestamp": "2026-03-08T11:54:57Z",
"value": "0"
}
],
"activity": true,
"scalerError": null
}
currentMetrics:
- external:
current:
averageValue: "0"
metric:
name: s0-forgejo
selector:
matchLabels:
scaledobject.keda.sh/name: forgejo-runners-scaledobject
type: External
Yet the HPA always scales to 1, it is never paused by keda to sacle to 0
status:
conditions:
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: recommended size matches current size
reason: ReadyForNewScale
status: "True"
type: AbleToScale
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: 'the HPA was able to successfully calculate a replica count from external
metric s0-forgejo(&LabelSelector{MatchLabels:map[string]string{scaledobject.keda.sh/name:
forgejo-runners-scaledobject,},MatchExpressions:[]LabelSelectorRequirement{},})'
reason: ValidMetricFound
status: "True"
type: ScalingActive
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: the desired replica count is less than the minimum replica count
reason: TooFewReplicas
status: "True"
type: ScalingLimited
Expected Behavior
I would expect the scaled object tell the HPA to pause scaling to take over the scaling when metrics all show 0
Actual Behavior
HPA always takes precedence over ScaledObject
Steps to Reproduce the Problem
ScaledObject:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
annotations:
argocd.argoproj.io/tracking-id: runners-app-of-apps:keda.sh/ScaledObject:forgejo/forgejo-runners-scaledobject
autoscaling.keda.sh/paused: "false"
finalizers:
- finalizer.keda.sh
generation: 6
labels:
kubevirt-manager.io/managed: "true"
scaledobject.keda.sh/name: forgejo-runners-scaledobject
name: forgejo-runners-scaledobject
namespace: forgejo
spec:
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
policies:
- periodSeconds: 30
type: Pods
value: 1
stabilizationWindowSeconds: 60
scaleUp:
policies:
- periodSeconds: 5
type: Pods
value: 1
stabilizationWindowSeconds: 10
cooldownPeriod: 60
initialCooldownPeriod: 10
maxReplicaCount: 10
minReplicaCount: 0
pollingInterval: 5
scaleTargetRef:
apiVersion: pool.kubevirt.io/v1beta1
kind: VirtualMachinePool
name: example-pool
triggers:
- authenticationRef:
name: runner-credentials
metadata:
address: https://git.example.org
global: "false"
labels: self-hosted
name: example
owner: small-hack
name: trig_one
type: forgejo-runner
status:
authenticationsTypes: runner-credentials
compositeScalerName: composite-metric
conditions:
- message: ScaledObject is defined correctly and is ready for scaling
reason: ScaledObjectReady
status: "True"
type: Ready
- message: Scaling is performed because triggers are active
reason: ScalerActive
status: "True"
type: Active
- message: No fallbacks are active on this scaled object
reason: NoFallbackFound
status: "False"
type: Fallback
- status: "False"
type: Paused
externalMetricNames:
- s0-forgejo
health:
s0-forgejo:
numberOfFailures: 0
status: Happy
hpaName: keda-hpa-forgejo-runners-scaledobject
lastActiveTime: "2026-03-08T12:06:42Z"
originalReplicaCount: 1
scaleTargetGVKR:
group: pool.kubevirt.io
kind: VirtualMachinePool
resource: virtualmachinepools
version: v1beta1
scaleTargetKind: pool.kubevirt.io/v1beta1.VirtualMachinePool
triggersActivity:
s0-forgejo:
isActive: true
triggersTypes: forgejo-runner
The HPA created by the scaledObject:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
annotations:
argocd.argoproj.io/tracking-id: runners-app-of-apps:keda.sh/ScaledObject:forgejo/forgejo-runners-scaledobject
autoscaling.keda.sh/paused: "false"
labels:
app.kubernetes.io/managed-by: keda-operator
app.kubernetes.io/name: keda-hpa-forgejo-runners-scaledobject
app.kubernetes.io/part-of: forgejo-runners-scaledobject
app.kubernetes.io/version: 2.19.0
kubevirt-manager.io/managed: "true"
scaledobject.keda.sh/name: forgejo-runners-scaledobject
name: keda-hpa-forgejo-runners-scaledobject
namespace: forgejo
ownerReferences:
- apiVersion: keda.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: ScaledObject
name: forgejo-runners-scaledobject
uid: 7ee4c7c4-0e8c-4a7c-a4ac-6adc330c29f1
spec:
behavior:
scaleDown:
policies:
- periodSeconds: 30
type: Pods
value: 1
selectPolicy: Max
stabilizationWindowSeconds: 60
scaleUp:
policies:
- periodSeconds: 5
type: Pods
value: 1
selectPolicy: Max
stabilizationWindowSeconds: 10
maxReplicas: 10
metrics:
- external:
metric:
name: s0-forgejo
selector:
matchLabels:
scaledobject.keda.sh/name: forgejo-runners-scaledobject
target:
averageValue: "1"
type: AverageValue
type: External
minReplicas: 1
scaleTargetRef:
apiVersion: pool.kubevirt.io/v1beta1
kind: VirtualMachinePool
name: example-pool
status:
conditions:
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: recommended size matches current size
reason: ReadyForNewScale
status: "True"
type: AbleToScale
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: 'the HPA was able to successfully calculate a replica count from external
metric s0-forgejo(&LabelSelector{MatchLabels:map[string]string{scaledobject.keda.sh/name:
forgejo-runners-scaledobject,},MatchExpressions:[]LabelSelectorRequirement{},})'
reason: ValidMetricFound
status: "True"
type: ScalingActive
- lastTransitionTime: "2026-03-08T11:47:49Z"
message: the desired replica count is less than the minimum replica count
reason: TooFewReplicas
status: "True"
type: ScalingLimited
currentMetrics:
- external:
current:
averageValue: "0"
metric:
name: s0-forgejo
selector:
matchLabels:
scaledobject.keda.sh/name: forgejo-runners-scaledobject
type: External
currentReplicas: 1
desiredReplicas: 1
Logs from KEDA operator
2026-03-08 13:10:27.734
{
"level": "debug",
"ts": "2026-03-08T12:10:27Z",
"logger": "scale_handler",
"msg": "Scaler for scaledObject is active",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"scaler": "trig_one",
"metricName": "s0-forgejo"
}
2026-03-08 13:10:27.734
{
"level": "debug",
"ts": "2026-03-08T12:10:27Z",
"logger": "fallback",
"msg": "Fallback is not enabled, hence skipping the health update to the scaledobject",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject"
}
2026-03-08 13:10:27.734
{
"level": "debug",
"ts": "2026-03-08T12:10:27Z",
"logger": "scale_handler",
"msg": "Getting metrics and activity from scaler",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"scaler": "trig_one",
"metricName": "s0-forgejo",
"metrics": [
{
"metricName": "s0-forgejo",
"metricLabels": null,
"timestamp": "2026-03-08T12:10:27Z",
"value": "0"
}
],
"activity": true,
"scalerError": null
}
2026-03-08 13:10:22.729
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "scale_handler",
"msg": "Scaler for scaledObject is active",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"scaler": "trig_one",
"metricName": "s0-forgejo"
}
2026-03-08 13:10:22.729
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "fallback",
"msg": "Fallback is not enabled, hence skipping the health update to the scaledobject",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject"
}
2026-03-08 13:10:22.729
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "scale_handler",
"msg": "Getting metrics and activity from scaler",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"scaler": "trig_one",
"metricName": "s0-forgejo",
"metrics": [
{
"metricName": "s0-forgejo",
"metricLabels": null,
"timestamp": "2026-03-08T12:10:22Z",
"value": "0"
}
],
"activity": true,
"scalerError": null
}
2026-03-08 13:10:22.247
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "grpc_server",
"msg": "Providing metrics",
"scaledObjectName": "forgejo-runners-scaledobject",
"scaledObjectNamespace": "forgejo",
"metrics": "&ExternalMetricValueList{ListMeta:{ <nil>},Items:[]ExternalMetricValue{ExternalMetricValue{MetricName:s0-forgejo,MetricLabels:map[string]string{},Timestamp:2026-03-08 12:10:22.247593549 +0000 UTC m=+54028.719744875,WindowSeconds:nil,Value:{{0 -3} {<nil>} DecimalSI},},},}"
}
2026-03-08 13:10:22.247
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "fallback",
"msg": "Fallback is not enabled, hence skipping the health update to the scaledobject",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject"
}
2026-03-08 13:10:22.247
{
"level": "debug",
"ts": "2026-03-08T12:10:22Z",
"logger": "scale_handler",
"msg": "Getting metrics from trigger",
"scaledObject.Namespace": "forgejo",
"scaledObject.Name": "forgejo-runners-scaledobject",
"trigger": "trig_one",
"metricName": "s0-forgejo",
"metrics": [
{
"metricName": "s0-forgejo",
"metricLabels": null,
"timestamp": "2026-03-08T12:10:22Z",
"value": "0"
}
],
"scalerError": null
}
KEDA Version
2.19.0
Kubernetes Version
1.34
Platform
Other
Scaler Details
Forgejo
Would you be open to contributing a fix?
None
Anything else?
No response
Report
I am unable to get my
ScaledObjectto scale myHPAto 0.My deployment has replicas set to 0
The scaling metric is correctly read from the source as 0
{ "level": "debug", "ts": "2026-03-08T11:54:57Z", "logger": "scale_handler", "msg": "Getting metrics and activity from scaler", "scaledObject.Namespace": "forgejo", "scaledObject.Name": "forgejo-runners-scaledobject", "scaler": "trig_one", "metricName": "s0-forgejo", "metrics": [ { "metricName": "s0-forgejo", "metricLabels": null, "timestamp": "2026-03-08T11:54:57Z", "value": "0" } ], "activity": true, "scalerError": null }my
scaledObjectminReplicaCount is set to 0The HPA sees the current average value as 0
Yet the HPA always scales to 1, it is never paused by keda to sacle to 0
Expected Behavior
I would expect the scaled object tell the HPA to pause scaling to take over the scaling when metrics all show 0
Actual Behavior
HPA always takes precedence over ScaledObject
Steps to Reproduce the Problem
ScaledObject:
The HPA created by the scaledObject:
Logs from KEDA operator
KEDA Version
2.19.0
Kubernetes Version
1.34
Platform
Other
Scaler Details
Forgejo
Would you be open to contributing a fix?
None
Anything else?
No response