kubectl wait --for=condition: Usage, Options & Common CI Errors
Block the pipeline until a resource actually reaches a condition.
kubectl wait --for=condition blocks until objects reach a named condition (or a timeout fires), the right way to make CI wait for readiness instead of sleeping. It returns non-zero on timeout, so a stuck deploy fails the step.
What it does
kubectl wait --for=condition=Ready pod/NAME polls until the condition is true; --for=condition=Available works for Deployments, --for=condition=complete for Jobs. --timeout bounds the wait, -l selects multiple objects, and --for=delete waits for an object to disappear. Newer kubectl also supports --for=jsonpath for arbitrary field values.
Common usage
kubectl wait --for=condition=Ready pod/my-pod --timeout=120s
kubectl wait --for=condition=Available deploy/web --timeout=180s
kubectl wait --for=condition=complete job/migrate --timeout=300s
kubectl wait --for=delete pod/my-pod --timeout=60s
kubectl wait --for=jsonpath='{.status.phase}'=Running pod -l app=webCommon errors in CI
The defining trap is "error: no matching resources found": wait does not block for an object to be created - if the resource does not exist yet (the apply has not landed, or a race), wait exits immediately with that error. Create first, then wait, or wrap in a small retry. "timed out waiting for the condition" is the healthy failure mode: the resource never became Ready within --timeout, which correctly fails the step - pair it with describe and logs --previous to find why. Waiting on condition=Ready for a Job is wrong; Jobs use condition=complete.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes