ahmetb/kubectx · warning
failed to save the previous namespace to file: %w
Error message
failed to save the previous namespace to file: %w
What it means
If the namespace actually changed (curNS != ns), switchNamespace records the old namespace in the per-context history file via f.Save(curNS) so `kubens -` can swap back. This error wraps a failure writing that history file — a filesystem-level problem, not a cluster or kubeconfig issue. Note the kubeconfig was already saved, so the switch itself succeeded; only the back/forth bookkeeping failed. Thrown at cmd/kubens/switch.go:95.
Source
Thrown at cmd/kubens/switch.go:95
if !force {
ok, err := namespaceExists(kc, ns)
if err != nil {
return "", fmt.Errorf("failed to query if namespace exists (is cluster accessible?): %w", err)
}
if !ok {
return "", fmt.Errorf("no namespace exists with name \"%s\"", ns)
}
}
if err := kc.SetNamespace(ctx, ns); err != nil {
return "", fmt.Errorf("failed to change to namespace \"%s\": %w", ns, err)
}
if err := kc.Save(); err != nil {
return "", fmt.Errorf("failed to save kubeconfig file: %w", err)
}
if curNS != ns {
if err := f.Save(curNS); err != nil {
return "", fmt.Errorf("failed to save the previous namespace to file: %w", err)
}
}
return ns, nil
}
func namespaceExists(kc *kubeconfig.Kubeconfig, ns string) (bool, error) {
// for tests
if os.Getenv("_MOCK_NAMESPACES") != "" {
return ns == "ns1" || ns == "ns2", nil
}
clientset, err := newKubernetesClientSet(kc)
if err != nil {
return false, fmt.Errorf("failed to initialize k8s REST client: %w", err)
}
namespace, err := clientset.CoreV1().Namespaces().Get(context.Background(), ns, metav1.GetOptions{})
if errors2.IsNotFound(err) {View on GitHub (pinned to 12ad6fb22e)
Solutions
- Ensure the state directory is writable: mkdir -p ~/.kube/kubens && chmod u+w ~/.kube/kubens
- Check $HOME is set and writable in the environment where kubens runs
- Free disk space / raise quota if the filesystem is full
- The namespace switch already took effect; only '-' history is lost — re-save by switching namespaces once more after fixing the directory
Example fix
// before # ~/.kube/kubens missing (cleanup job removed it) kubens prod # switch succeeds, history save fails // after mkdir -p ~/.kube/kubens kubens default && kubens prod # history file recreated
Defensive patterns
Strategy: fallback
Validate before calling
dir := stateDir()
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("kubens state dir unwritable, '-' history disabled: %w", err)
} Try / catch
if err := f.Save(curNS); err != nil {
// non-fatal: namespace switch already succeeded; log and continue
fmt.Fprintf(stderr, "warning: could not record previous namespace: %v\n", err)
} Prevention
- Pre-create ~/.kube/kubens with user-writable permissions in provisioning scripts
- Ensure $HOME is set and writable in CI, cron, and containers
- Exclude the kubens state directory from aggressive cleanup jobs
- Treat this error as non-fatal — the switch itself has already been persisted
When it happens
Trigger: f.Save(curNS) errors because the state directory (~/.kube/kubens or XDG equivalent) does not exist and cannot be created, is read-only, has wrong permissions, or the disk is full.
Common situations: HOME unset or pointing to a read-only path in CI/cron; kubens state directory deleted by a cleanup job while the process runs; read-only root filesystem in minimal containers; disk quota exceeded.
Related errors
- failed to load previous namespace from file: %w
- No previous namespace found for current context (%s)
- failed to get current context: %w
- failed to get current namespace: %w
- failed to query if namespace exists (is cluster accessible?)
AI-assisted analysis of ahmetb/kubectx@12ad6fb22e (2026-09-02).
Data as JSON: /api/errors/b9b08a4beccdb720.
Report an issue: GitHub.