How to fix StatefulSet not ready in Kubernetes

KubernetesINTERMEDIATEHIGHUpdated Dec 6, 2025· 228 views

A StatefulSet shows "not ready" status when its pods fail to reach the Running and Ready state. This blocks orderly pod deployment since StatefulSets wait for each pod to be fully ready before starting the next one. The issue typically stems from storage failures, resource constraints, health check misconfigurations, or application startup problems.

Quick fix

Fixes StatefulSet not ready

kubectl get statefulset <name>
kubectl get statefulset <name> -o yaml
kubectl get pods -l app=<name>
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
  1. Check StatefulSet and pod status
  2. Inspect the first pod in detail
  3. Verify PersistentVolumeClaims are bound
  4. Check cluster and node resources
kubernetes — error
kubectl get statefulset <name>
kubectl get statefulset <name> -o yaml
kubectl get pods -l app=<name>
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
StatefulSet not ready

What this error means

A StatefulSet maintains a sticky identity for each pod and requires strict ordering: each pod (e.g., mysql-0, mysql-1, mysql-2) must become Running and Ready before the next pod is deployed. When you see "not ready" status, it means one or more pods are stuck in Pending, CrashLoopBackOff, ImagePullBackOff, or other non-Ready states. StatefulSets won't automatically proceed to deploy subsequent pods until earlier ones succeed. This is intentional—it prevents data corruption or initialization conflicts in stateful applications. Unlike Deployments, StatefulSets enforce strict ordering guarantees. If pod-0 fails, pod-1 won't start. This makes StatefulSet readiness failures block the entire application.

Typical symptoms

  • kubectl get statefulset shows 0/N ready (e.g., "0/3 ready")
  • kubectl describe statefulset lists pods with status "Pending" or "Not Ready"
  • Only the first pod (e.g., mysql-0) is created; subsequent pods don't appear
  • Pods are visible but stuck in non-Ready state (running containers but readiness probes failing)
  • PersistentVolumeClaims (PVCs) remain unbound or pending
  • Application logs show startup errors, database initialization failures, or network timeouts
  • StatefulSet updates or rollouts hang indefinitely

Common causes

  1. PersistentVolumeClaim (PVC) unbound or storage unavailable (most common)
  2. Insufficient CPU or memory preventing pod scheduling
  3. Readiness probe misconfiguration or excessive timeout settings
  4. Application startup failures (database connection issues, missing dependencies)
  5. Image pull errors (invalid image reference, missing registry credentials)
  6. Node pressure (memory, disk, or PID pressure) blocking pod scheduling
  7. DNS resolution failures preventing inter-pod communication
  8. StatefulSet headless service misconfiguration or missing

How to fix "StatefulSet not ready"

1Check StatefulSet and pod status

Get the overall status:

bash
kubectl get statefulset <name>
kubectl get statefulset <name> -o yaml
kubectl get pods -l app=<name>
kubectl get events -n <namespace> --sort-by='.lastTimestamp'

Look at the READY column (e.g., "0/3" means no pods ready). The Events section shows recent warnings or errors that blocked pod creation.

2Inspect the first pod in detail

Since StatefulSets deploy sequentially, always start with pod-0:

bash
kubectl describe pod <statefulset>-0
kubectl logs <statefulset>-0
kubectl logs <statefulset>-0 --previous  # If pod crashed

The "Events" section of describe shows:
- "Pending": Pod waiting for resources or PVC binding
- "CrashLoopBackOff": Container exits immediately (check logs)
- "ImagePullBackOff": Image pull failed
- "Not Ready": Container running but readiness probe failing

3Verify PersistentVolumeClaims are bound

StatefulSets require persistent storage. Check PVC status:

bash
kubectl get pvc
kubectl describe pvc <statefulset>-<ordinal>  # e.g., mysql-data-mysql-0

Look for "Status: Bound". If Status is "Pending":
- No PersistentVolume available (check kubectl get pv)
- Storage provisioner (e.g., EBS, NFS) not configured or failing
- Storage class doesn't exist: kubectl get storageclass

If PVC is stuck, describe it:

bash
kubectl describe pvc <name>

The Events section shows provisioning failures.

4Check cluster and node resources

Insufficient resources often prevent pod scheduling:

bash
kubectl top nodes
kubectl top pods -n <namespace>
kubectl describe nodes

Look for:
- High CPU/memory utilization
- "Insufficient cpu" or "Insufficient memory" in pod events
- Disk pressure on nodes

If constrained, either:
- Scale down other workloads: kubectl scale deployment <name> --replicas=1
- Add nodes to the cluster
- Reduce StatefulSet replica count for testing: kubectl scale statefulset <name> --replicas=1

5Verify the headless service exists

StatefulSets require a headless service (clusterIP: None) for DNS:

bash
kubectl get service <statefulset-name>
kubectl describe service <statefulset-name>

The service selector should match the StatefulSet labels. Expected output:
- ClusterIP: None (headless)
- Selector: app=<statefulset-name> (or your label)

If missing, create it:

yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
  - port: 3306
    name: mysql
6Check readiness probe configuration

Misconfigured probes often fail at startup. View current probe settings:

bash
kubectl get statefulset <name> -o yaml | grep -A15 readinessProbe:

Common issues:
- initialDelaySeconds too low (should give app time to start)
- timeoutSeconds too low (app is slow)
- Probe command/endpoint doesn't exist yet

Test the probe manually:

bash
kubectl exec -it <statefulset>-0 -- <probe-command>
# Example: curl http://localhost:8080/health

If it fails, the app isn't ready. Increase delays:

yaml
readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 60  # Increase from default
  timeoutSeconds: 10
  periodSeconds: 10
  failureThreshold: 3
7Verify image exists and is accessible

Image pull failures block StatefulSet startup:

bash
kubectl get statefulset <name> -o yaml | grep image:
kubectl describe pod <statefulset>-0 | grep -i "image"

Test locally:

bash
docker pull <image:tag>  # Fails if unavailable or credentials wrong

For private registries, ensure imagePullSecrets:

bash
kubectl get secret
kubectl create secret docker-registry regcred \
  --docker-server=myregistry.com \
  --docker-username=user \
  --docker-password=pass

Add to StatefulSet:

yaml
spec:
  imagePullSecrets:
  - name: regcred
8Delete the stuck pod to trigger recovery

If debugging shows the issue is app-side (e.g., bad config), fix the underlying problem, then delete the pod:

bash
kubectl delete pod <statefulset>-0

The StatefulSet controller will recreate it. Since you fixed the issue (config, image, storage, probe settings), the new pod should become Ready.

Monitor recreation:

bash
kubectl get pods -w  # Watch mode

Once pod-0 is Ready, the StatefulSet will deploy pod-1, pod-2, etc.

Advanced notes

For database-backed StatefulSets (PostgreSQL, MySQL, MongoDB, Cassandra), initialization scripts may hang on first pod startup—allow extra time with initialDelaySeconds: 120 or more. Persistent storage setup differs by cloud provider: AWS uses EBS (storage class required), GCP uses persistent disks, Azure uses managed disks. Helm charts for StatefulSets often have readiness probe overrides—check values.yaml for timing parameters. In minikube or Docker Desktop with limited resources, reduce replicas: kubectl scale statefulset <name> --replicas=1 for testing. Multi-zone clusters may see slower PVC binding—use local storage classes for faster provisioning. ArgoCD/Flux should use syncPolicy.syncOptions: [AllowEmpty] to prevent sync failures during sequential pod deployment. StatefulSet ordinal ordering is strict: failures in early pods (mysql-0) block later pods (mysql-1, mysql-2). For rolling updates, use partition: N to limit which pods update at once. Rollback stuck updates with kubectl rollout undo statefulset <name>.

Frequently asked questions

What does "StatefulSet not ready" mean?
, mysql-0, mysql-1, mysql-2) must become Running and Ready before the next pod is deployed. When you see "not ready" status, it means one or more pods are stuck in Pending, CrashLoopBackOff, ImagePullBackOff, or other non-Ready states. StatefulSets won't automatically proceed to deploy subsequent pods until earlier ones succeed.
How do I fix "StatefulSet not ready"?
A StatefulSet shows "not ready" status when its pods fail to reach the Running and Ready state. This blocks orderly pod deployment since StatefulSets wait for each pod to be fully ready before starting the next one. The issue typically stems from storage failures, resource constraints, health check misconfigurations, or application startup problems.
What causes "StatefulSet not ready"?
PersistentVolumeClaim (PVC) unbound or storage unavailable (most common) Insufficient CPU or memory preventing pod scheduling Readiness probe misconfiguration or excessive timeout settings
Is the "StatefulSet not ready" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading