A Deployment rollout is degraded with ProgressDeadlineExceeded — diagnose the stall.
A rolling update is stuck: kubectl rollout status errors out and the Deployment shows ProgressDeadlineExceeded. Explain what that condition means, why old and new Pods coexist, and how you find the root cause.
$ kubectl rollout status deploy/api
Waiting for deployment "api" rollout to finish: 2 of 5 updated replicas are available...
error: deployment "api" exceeded its progress deadline
$ kubectl describe deploy api | sed -n '/Conditions/,/Events/p'
Type Status Reason
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
$ kubectl get pods -l app=api
api-new-1 0/1 Running 0 6m
Diagnose and fix.
ProgressDeadlineExceeded means the new ReplicaSet never reached enough Ready Pods within progressDeadlineSeconds; the rollout stalls, it does not auto-roll-back, and maxUnavailable keeps old Pods up. Describe a new Pod — usually readiness, ImagePull, capacity, or a PDB.
- ✗Expecting
ProgressDeadlineExceededto auto-roll-back rather than stall - ✗Not describing a new Pod to find why it never goes Ready
- ✗Ignoring readiness, ImagePull, capacity, and PDB as the usual roots
- →How do
maxUnavailableandmaxSurgeshape what stays available during the stall? - →When is
kubectl rollout undothe right call versus fixing the new Pods forward?
Solution
1. What the condition means
Progressing = False, ProgressDeadlineExceeded — the Deployment controller waited, but the new ReplicaSet never reached the required number of Ready Pods within progressDeadlineSeconds (default 600s). This is a stall, not a rollback: Kubernetes does not revert on its own.
2. Why old and new coexist
RollingUpdate honours maxUnavailable/maxSurge: old Pods are not removed until the new ones are Ready. Hence Available True (service is up on the old Pods) but Progressing False (the new ones never came up).
3. Root cause — from a new Pod
$ kubectl describe pod api-new-1 | sed -n '/Events/,$p'
Warning Unhealthy kubelet Readiness probe failed: HTTP 500 on /health
Common roots: readiness never passes (here), ImagePullBackOff, no capacity (FailedScheduling), or a PDB blocking eviction of the old Pods. Fix: clear the cause on the new Pods and the rollout resumes on its own; or kubectl rollout undo deploy/api.