hashicorp/nomad · error
error switching to ns %v: %v
Error message
error switching to ns %v: %v
What it means
This error is returned from netNS.Do() when ns.Set() fails to switch the calling thread into the target network namespace. It wraps the namespace file name and the underlying error (itself typically the unix.Setns failure from netNS.Set).
Source
Thrown at client/lib/nsutil/ns_linux.go:188
}
return nil
}
func (ns *netNS) Do(toRun func(NetNS) error) error {
if err := ns.errorIfClosed(); err != nil {
return err
}
containedCall := func(hostNS NetNS) error {
threadNS, err := GetCurrentNS()
if err != nil {
return fmt.Errorf("failed to open current netns: %v", err)
}
defer threadNS.Close()
// switch to target namespace
if err = ns.Set(); err != nil {
return fmt.Errorf("error switching to ns %v: %v", ns.file.Name(), err)
}
defer func() {
err := threadNS.Set() // switch back
if err == nil {
// Unlock the current thread only when we successfully switched back
// to the original namespace; otherwise leave the thread locked which
// will force the runtime to scrap the current thread, that is maybe
// not as optimal but at least always safe to do.
runtime.UnlockOSThread()
}
}()
return toRun(hostNS)
}
// save a handle to current network namespace
hostNS, err := GetCurrentNS()
if err != nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Grant CAP_SYS_ADMIN / run privileged, since setns into a netns requires it
- Confirm the owning container/task still lives so the namespace is valid
- Check the wrapped error for EPERM (capabilities), EINVAL (bad fd/ns), or EBADF (closed fd)
- Ensure the NetNS handle is open and not closed before Do()
- Review seccomp/AppArmor profiles for setns allowances
Example fix
// before
ns, _ := GetNS("/var/run/netns/foo")
ns.Do(func(ns NetNS) error { ... }) // EPERM unprivileged
// after
ns, err := GetNS("/var/run/netns/foo")
if err != nil { return err }
if err := ns.Do(func(ns NetNS) error { ... }); err != nil {
return fmt.Errorf("run in netns failed (needs CAP_SYS_ADMIN?): %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
func canSwitchTo(ns NetNS) error {
if !hasCapSysAdmin() {
return errors.New("setns into netns requires CAP_SYS_ADMIN")
}
return nil
} Type guard
func netnsAlive(nspath string) bool {
err := IsNSorErr(nspath)
return err == nil
} Try / catch
err := ns.Do(work)
if err != nil {
if strings.Contains(err.Error(), "error switching to ns") {
if !hasCapSysAdmin() {
return fmt.Errorf("run privileged: %w", err)
}
return fmt.Errorf("target netns may be gone; recreate handle: %w", err)
}
return err
} Prevention
- Run with CAP_SYS_ADMIN wherever setns is needed
- Refresh the NetNS handle if the target container restarted
- Keep seccomp/AppArmor profiles permissive for setns
- Check the wrapped errno (EPERM vs EINVAL vs EBADF) to target fixes
When it happens
Trigger: Calling Do() on a NetNS handle whose setns fails — missing CAP_SYS_ADMIN, target namespace destroyed, closed/invalid fd, or kernel security policy blocking setns(CLONE_NEWNET).
Common situations: Network namespace of an exited container; unprivileged execution (no SYS_ADMIN); Docker/Kubernetes security contexts dropping capabilities; seccomp filters disallowing setns.
Related errors
- Error switching to ns %v: %v
- Unable to find nobody user: %w
- Couldn't change owner/group of %v to (uid: %v, gid: %v): %w
- Failed to delete proc directory %q: %w
- error changing owner/group: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/496cdbe2c4097b7a.
Report an issue: GitHub.