# Deployment Not Fully Ready

> A Deployment reporting fewer ready replicas than its spec requests is running at reduced capacity right now. ZopNight compares desired against ready. A gap of 1 on a 10-replica service is degraded; the same gap on a 1-replica service is a full outage nothing has alerted on.

Source: https://zop.dev/integrations/kubernetes/recommendations/deployment-not-fully-ready
Updated: 2026-08-19

---

## Degraded is not the same as down, and both look the same here

The rule compares `spec.replicas` against `status.readyReplicas`. The gap is the finding.

What that gap means depends entirely on the denominator. Nine of ten ready is a service running
at 90% capacity (probably fine, worth knowing). Zero of one ready is a complete outage, and it
produces the identical shape of finding.

Read the ratio, not the difference.

## Why a Deployment sits partially ready

**Insufficient node capacity.** Pods are Pending because no node satisfies their requests. Common
after adding replicas without cluster autoscaling.

**Readiness failing.** Pods are Running but not passing their readiness probe: a dependency is
unavailable, or the probe is stricter than the application.

**Image pull failures.** Wrong tag, missing pull secret, registry rate limit. The pod never
starts.

**Scheduling constraints unsatisfiable.** Node affinity, taints, or a topology spread constraint
that cannot be met with the nodes currently available.

The first two are by far the most frequent, and they need opposite responses. One is a capacity
problem, the other an application one.

## Persistent versus transient

Every rollout produces a temporary gap. That is the deployment strategy working, not a fault.

What matters is duration. A Deployment that has been short a replica for hours is stuck; one
short for ninety seconds is mid-update. The rule cannot see how long the state has held, so a
finding here is a prompt to check, not proof of a stuck workload.

## From readyReplicas to the pod describe events

```bash
kubectl get deploy -A -o json | jq -r '
  .items[] | select((.status.readyReplicas // 0) < .spec.replicas)
  | "\(.metadata.namespace)/\(.metadata.name)\t\(.status.readyReplicas // 0)/\(.spec.replicas)"'
```

Then go straight to the pods, where the actual reason lives:

```bash
kubectl get pods -n <ns> -l app=<name>
kubectl describe pod <pod> -n <ns> | tail -25
```

The `Events` section at the bottom of `describe` names the cause in almost every case.
