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

  1. Refresh the view (press 0 or wait for the watcher) — the namespace controller usually sets Active within seconds
  2. Verify the real phase: `kubectl get ns <name> -o jsonpath='{.status.phase}'`
  3. If the phase stays empty, inspect namespace controller health and apiserver/etcd logs
  4. 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

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


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