istio/istio · error

Error switching to ns fd %v: %v

Error message

Error switching to ns fd %v: %v

What it means

unix.Setns(fd, CLONE_NEWNET) failed while switching the current thread into a pod's network namespace. Setns requires the fd to reference a live netns and the caller to hold CAP_SYS_ADMIN in the target namespace's user namespace.

Source

Thrown at cni/pkg/nodeagent/netns_linux.go:69

	return stats.Ino, err
}

func OpenNetns(nspath string) (NetnsCloser, error) {
	n, err := netns.GetNS(nspath)
	if err != nil {
		return nil, err
	}
	i, err := inodeForFd(n)
	if err != nil {
		n.Close()
		return nil, err
	}
	return &NetnsWrapper{innerNetns: n, inode: i}, nil
}

func NetnsSet(n NetnsFd) error {
	if err := unix.Setns(int(n.Fd()), unix.CLONE_NEWNET); err != nil {
		return fmt.Errorf("Error switching to ns fd %v: %v", n.Fd(), err)
	}
	return nil
}

// inspired by netns.Do() but with an existing fd.
func NetnsDo(fdable NetnsFd, toRun func() error) error {
	containedCall := func() error {
		threadNS, err := netns.GetCurrentNS()
		if err != nil {
			return fmt.Errorf("failed to open current netns: %v", err)
		}
		defer threadNS.Close()

		// switch to target namespace
		if err = NetnsSet(fdable); err != nil {
			return err
		}
		defer func() {

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Run the agent privileged or with CAP_SYS_ADMIN (as istio-cni requires) and check PSA/PSP/SCC policies
  2. Validate the fd is open and points to a netns before calling (fstat S_IFSOCK / check /proc/self/fd)
  3. Handle EINVAL/EBADF races by re-fetching the netns handle or skipping cleanup for gone pods
  4. Ensure seccomp profile allows setns
Defensive patterns

Strategy: validation

Validate before calling

// verify the fd is an open netns before setns
var st unix.Stat_t
if err := unix.Fstat(int(fd.Fd()), &st); err != nil {
    return fmt.Errorf("netns fd invalid: %w", err)
}

Try / catch

if err := NetnsSet(nsFd); err != nil {
    if errors.Is(err, syscall.EPERM) {
        return errors.New("setns denied: run istio-cni with CAP_SYS_ADMIN/privileged")
    }
    if errors.Is(err, syscall.EINVAL) {
        return errors.New("setns: fd is not a network namespace (pod gone?)")
    }
    return err
}

Prevention

When it happens

Trigger: NetnsSet called with a closed/stale fd (pod netns already destroyed), fd not actually a netns fd, or the calling process lacks CAP_SYS_ADMIN/privileged — EINVAL for bad fd, EPERM for capability.

Common situations: istio-cni agent not privileged or missing CAP_SYS_ADMIN; race where the pod is deleted and its netns fd closed before the switch; seccomp profiles blocking setns; restricted PodSecurity policies.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/91b55da149f154d2. Report an issue: GitHub.