derailed/k9s · warning
namespace not ready
Error message
namespace not ready
What it means
Returned by `Namespace.diagnose` (internal/render/ns.go) when a namespace's `status.phase` is neither `Active` nor `Terminating`. The Kubernetes API only defines those two phases, so any other value means the object is incomplete or not yet observed: typically an empty phase on a just-created namespace before the namespace controller sets it, or an object converted from an Unstructured payload that lacked `status.phase`. It surfaces in the VALID column of the namespace view via `AsStatus(n.diagnose(...))`.
Source
Thrown at internal/render/ns.go:115
func (n Namespace) Healthy(_ context.Context, o any) error {
res, ok := o.(*unstructured.Unstructured)
if !ok {
slog.Error("Expected *Unstructured, but got", slogs.Type, fmt.Sprintf("%T", o))
return nil
}
var ns v1.Namespace
err := runtime.DefaultUnstructuredConverter.FromUnstructured(res.Object, &ns)
if err != nil {
slog.Error("Failed to convert Unstructured to Namespace", slogs.Type, fmt.Sprintf("%T", o), slog.String("error", err.Error()))
return nil
}
return n.diagnose(ns.Status.Phase)
}
func (Namespace) diagnose(phase v1.NamespacePhase) error {
if phase != v1.NamespaceActive && phase != v1.NamespaceTerminating {
return errors.New("namespace not ready")
}
return nil
}
View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Refresh the view (press 0 or wait for the watcher) — the namespace controller usually sets Active within seconds
- Verify the real phase: `kubectl get ns <name> -o jsonpath='{.status.phase}'`
- If the phase stays empty, inspect namespace controller health and apiserver/etcd logs
- For fake/virtual clusters, populate status.phase or accept the VALID warning
Defensive patterns
Strategy: validation
Validate before calling
// Only diagnose namespaces with a known phase:
phase := ns.Status.Phase
if phase == v1.NamespaceActive || phase == v1.NamespaceTerminating {
err = nsRenderer.diagnose(phase)
} Type guard
func nsPhaseReady(p v1.NamespacePhase) bool {
return p == v1.NamespaceActive || p == v1.NamespaceTerminating
} Try / catch
if err := diagnose(ns.Status.Phase); err != nil {
// requeue/refresh: phase not yet observed
} Prevention
- Wait one controller sync after creating namespaces before asserting readiness
- Populate status.phase in fake/test apiservers
- Treat VALID warnings as observations, not failures
When it happens
Trigger: `runtime.DefaultUnstructuredConverter.FromUnstructured` succeeds but the resulting `v1.Namespace.Status.Phase` is "" (or any non-Active/Terminating value), so `diagnose` returns the error. Common with namespaces listed in the instant between creation and the controller writing status, or with fake/test clusters that never populate phase.
Common situations: Freshly created namespace viewed immediately (`kubectl create ns x` then list in k9s); watch caches served by a broken etcd/apiserver; CRD-backed or virtual clusters (vcluster, fake apiserver) that do not implement namespace lifecycle; stale cached objects after control-plane restart.
Related errors
- node is cordoned
- user is not authorized to list pods metrics
- failed benchmark
- expecting a switchable resource
- expecting a switchable resource
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/715dcf3f41e8e08b.
Report an issue: GitHub.