HorizontalPodAutoscalers configured with minReplicas set to 0
What does ZopNight detect here?
ZopNight flags a Kubernetes HorizontalPodAutoscaler on EKS, GKE or AKS whose `minReplicas` is 0. Scaling to zero only works with Object or External metrics and the `HPAScaleToZero` feature gate; CPU and memory can only be measured on running pods, so a resource-metric HPA has no signal to bring a workload back from zero.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1745 · RC-1845 · RC-1945 |
| Category | reliability |
| Severity | medium |
| Metric | spec.minReplicas |
| Threshold | equals 0 |
| Source | ZopNight |
| Permissions used | list horizontalpodautoscalers.autoscaling |
Where it applies
Zero is a floor the autoscaler may not climb back from
minReplicas defaults to 1. The
HPA API reference
allows 0 only when the HPAScaleToZero feature gate is enabled and at least one Object or
External metric is configured. The
horizontal pod autoscaling page
explains why: scaling to zero is not available for resource metrics such as CPU or memory
utilization, because those can only be measured on running pods. With no pods there is no CPU
reading, and nothing tells the controller to add the first replica.
The feature gate’s status depends on the Kubernetes version. The API reference describes it as alpha, while the current autoscaling page lists it as beta and enabled by default from v1.37, with the gate needed on both the API server and the controller manager. On a managed EKS, GKE or AKS control plane you do not set feature gates yourself, so what works is whatever your version ships.
Listing HPAs with a zero floor
kubectl get hpa -A -o json | jq -r ' .items[] | select(.spec.minReplicas == 0) | "\(.metadata.namespace)/\(.metadata.name) metrics=\([.spec.metrics[]?.type] | join(","))"'An HPA listing only Resource metrics is the risky case. One listing External or Object
metrics may be a deliberate scale-to-zero design.
What ZopNight checks
The rule reads minReplicas from the HPA it collected and fires when it is exactly 0. It does
not read the metric types or the feature gate, so a correctly built scale-to-zero HPA is flagged
alongside a broken one. When minReplicas is not reported, the HPA is skipped. There is no
window; the finding clears once the minimum is 1 or more.
Related settings reported elsewhere
The other HPA configuration checks cover different values of the same fields: HPA cannot scale for a maximum of 1, HPA pinned for minimum equal to maximum, and HPA has no metrics for an empty metric list. A Deployment scaled to zero by hand, rather than by an HPA, is reported by Stopped deployment.
Availability risk, not a saving
This medium-severity reliability finding has no savings figure. Scale-to-zero is attractive for cost, but only when something reliable wakes the workload up again.
Choosing a safe floor
- Check the metric types in the HPA spec. If they are all
Resourcemetrics, setminReplicasto 1 or more:kubectl patch hpa <name> -p '{"spec":{"minReplicas":1}}'. - If you want scale-to-zero, drive it from an External or Object metric that exists while the workload is idle, such as a queue length, and confirm your cluster version supports it.
- While an HPA holds a workload at zero, the current docs describe a
ScaledToZerocondition on its status; check it withkubectl describe hpa <name>after the next idle period.