Summary
WaitForDeploymentAvailable (pkg/k8s/wait.go) can fail a redeploy with
could not find current pod-template-hash for deployment <name> when the live
Deployment has 0 desired replicas. This is reachable today via the keda
(HTTP-scaler) deployer, whose ScaledObject scales idle functions down to zero.
Note: this is reasoned from the code, not yet reproduced (it's a timing race).
Filing so the analysis is tracked; repro TBD.
Details
WaitForDeploymentAvailable re-fetches the live Deployment on every poll tick:
deployment, err := clientset.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{})
...
return checkIfDeploymentIsAvailable(ctx, clientset, deployment)
checkIfDeploymentIsAvailable finds the active ReplicaSet by looking for one with
*rs.Spec.Replicas > 0. A Deployment sitting at 0 desired replicas has no such
ReplicaSet, so currentPodTemplateHash stays empty and the function returns an error
(pkg/k8s/wait.go):
if currentPodTemplateHash == "" {
return false, fmt.Errorf("could not find current pod-template-hash for deployment %s", deployment.Name)
}
The func deployer itself always applies replicas >= 1 (pkg/k8s/deployer.go), so
it never creates a 0-replica Deployment. But because the wait inspects live state,
reachability is governed by what KEDA does during the wait, not by what func wrote:
- An idle keda-HTTP function has been scaled to 0 replicas by KEDA.
- User redeploys. func applies the Deployment with
replicas: 1, then starts polling.
- If the KEDA controller reasserts 0 replicas on the live Deployment before the poll
observes it as ready, the live fetch returns spec.replicas == 0, and the wait
returns the pod-template-hash error — failing the redeploy.
Suggested fix
Short-circuit when there is nothing to wait for:
desiredReplicas := *deployment.Spec.Replicas
if desiredReplicas == 0 {
return true, nil // no replicas desired; nothing to wait for
}
This also unblocks any future spec-level scale-to-zero on the raw/keda Deployment.
Notes
- Reasoned from code; not reproduced. A repro needs a cluster with KEDA and an idle,
scaled-to-zero HTTP function being redeployed.
- Fix is small and self-contained but likely wants a repro or unit test first, hence
filing as an issue rather than an immediate PR.
Summary
WaitForDeploymentAvailable(pkg/k8s/wait.go) can fail a redeploy withcould not find current pod-template-hash for deployment <name>when the liveDeployment has 0 desired replicas. This is reachable today via the keda
(HTTP-scaler) deployer, whose ScaledObject scales idle functions down to zero.
Details
WaitForDeploymentAvailablere-fetches the live Deployment on every poll tick:checkIfDeploymentIsAvailablefinds the active ReplicaSet by looking for one with*rs.Spec.Replicas > 0. A Deployment sitting at 0 desired replicas has no suchReplicaSet, so
currentPodTemplateHashstays empty and the function returns an error(
pkg/k8s/wait.go):The func deployer itself always applies
replicas >= 1(pkg/k8s/deployer.go), soit never creates a 0-replica Deployment. But because the wait inspects live state,
reachability is governed by what KEDA does during the wait, not by what func wrote:
replicas: 1, then starts polling.observes it as ready, the live fetch returns
spec.replicas == 0, and the waitreturns the pod-template-hash error — failing the redeploy.
Suggested fix
Short-circuit when there is nothing to wait for:
This also unblocks any future spec-level scale-to-zero on the raw/keda Deployment.
Notes
scaled-to-zero HTTP function being redeployed.
filing as an issue rather than an immediate PR.