derailed/k9s · warning

unexpected status %s

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.

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)

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.