derailed/k9s · warning

unexpected status

Error message

unexpected status %s

What it means

PersistentVolumeClaim.diagnose is the VALID-column health check: it accepts only the strings 'Bound' and 'Available' and returns 'unexpected status <phase>' for anything else, rendered via AsStatus. Since a PVC's actual phases are Bound, Pending and Lost — 'Available' is a PV phase, not a PVC one — every Pending or Lost claim shows this diagnostic. It reports cluster state (the claim is not usable yet) and never leaves Render as an error.

Solutions

  1. Run kubectl describe pvc <name> and read Events for the exact binding failure
  2. Fix spec.storageClassName (create the class or correct the name) so a PV can be provisioned
  3. For WaitForFirstConsumer claims, start the consuming pod so provisioning begins
  4. For Lost claims, recreate the claim after restoring or removing the underlying PV

Example fix

# before: PVC Pending, storageClassName references a missing class
kubectl get pvc myclaim -o jsonpath='{.status.phase}'
# Pending
# after: point at an existing class so binding proceeds
kubectl patch pvc myclaim -p '{"spec":{"storageClassName":"standard"}}'
Defensive patterns

Strategy: validation

Validate before calling

# find claims that will show the diagnostic
kubectl get pvc -A --field-selector=status.phase=Pending
kubectl get pvc -A --field-selector=status.phase=Lost

Prevention

When it happens

Trigger: Opening the PVC view while a claim is Pending (no matching StorageClass, WaitForFirstConsumer binding waiting for a consumer pod, capacity or topology limits unmet) or Lost (its bound PV disappeared). Any phase string other than Bound/Available trips the check.

Common situations: Deploying a workload before its StorageClass exists; storageClassName typo or missing default class; WaitForFirstConsumer claims with no consumer scheduled; deleted PV leaving the claim Lost.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/c50ef43ec1557f76. Report an issue: GitHub.

Appendix: source

Thrown at internal/render/pvc.go:104

	r.Fields = model1.Fields{
		pvc.Namespace,
		pvc.Name,
		string(phase),
		pvc.Spec.VolumeName,
		capacity,
		accessModes,
		class,
		mapToStr(pvc.Labels),
		AsStatus(p.diagnose(string(phase))),
		ToAge(pvc.GetCreationTimestamp()),
	}

	return nil
}

func (PersistentVolumeClaim) diagnose(r string) error {
	if r != "Bound" && r != "Available" {
		return fmt.Errorf("unexpected status %s", r)
	}
	return nil
}

View on GitHub (pinned to 2d3ccc6ba2)