hashicorp/nomad · error
error from unshare: %v
Error message
error from unshare: %v
What it means
After saving the original namespace, NewNS calls unix.Unshare(CLONE_NEWNET) on the locked thread to create a fresh network namespace. If the kernel rejects the unshare, the error is wrapped as 'error from unshare'. This means the process lacks the privileges or the kernel disallows creating a new network namespace at that point.
Source
Thrown at client/lib/nsutil/netns_linux.go:107
// the caller of this function
go (func() {
defer wg.Done()
runtime.LockOSThread()
// Don't unlock. By not unlocking, golang will kill the OS thread when the
// goroutine is done (for go1.10+)
var origNS NetNS
origNS, err = GetNS(getCurrentThreadNetNSPath())
if err != nil {
err = fmt.Errorf("failed to get the current netns: %v", err)
return
}
defer origNS.Close()
// create a new netns on the current thread
err = unix.Unshare(unix.CLONE_NEWNET)
if err != nil {
err = fmt.Errorf("error from unshare: %v", err)
return
}
// Put this thread back to the orig ns, since it might get reused (pre go1.10)
defer origNS.Set()
// bind mount the netns from the current thread (from /proc) onto the
// mount point. This causes the namespace to persist, even when there
// are no threads in the ns.
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
if err != nil {
err = fmt.Errorf("failed to bind mount ns at %s: %v", nsPath, err)
}
})()
wg.Wait()
if err != nil {
return nil, fmt.Errorf("failed to create namespace: %v", err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Run the program with CAP_SYS_ADMIN or as root (or via a setuid helper)
- Enable unprivileged namespace creation: sysctl -w kernel.unprivileged_userns_clone=1 (distro-dependent)
- Raise user namespace limits: check/raise /proc/sys/user/max_user_namespaces
- Confirm the kernel is compiled with CONFIG_NET_NS=y
Example fix
// before: EPERM from unshare in unprivileged container // after: // docker run --cap-add NET_ADMIN --cap-add SYS_ADMIN myimage ns, err := nsutil.NewNS()
Defensive patterns
Strategy: try-catch
Validate before calling
out, _ := exec.Command("unshare", "-n", "true").CombinedOutput()
if out != nil || execErr != nil {
return errors.New("this environment cannot create network namespaces (need CAP_SYS_ADMIN or userns)")
} Try / catch
ns, err := nsutil.NewNS()
if err != nil && strings.Contains(err.Error(), "error from unshare") {
if errors.Is(err, os.ErrPermission) {
return fmt.Errorf("missing CAP_SYS_ADMIN for unshare(CLONE_NEWNET): %w", err)
}
return err
} Prevention
- Run with CAP_SYS_ADMIN or enable unprivileged user namespaces
- Check /proc/sys/user/max_user_namespaces limits on multi-tenant hosts
- Smoke-test namespace creation at service startup and fail fast with a clear message
- Confirm kernel has CONFIG_NET_NS enabled
When it happens
Trigger: unix.Unshare(CLONE_NEWNET) returns an error during NewNS — EPERM because the process lacks CAP_SYS_ADMIN, or failure because namespace limits (max_user_namespaces) are exhausted.
Common situations: Unprivileged users without user namespaces enabled (kernel.unprivileged_userns_clone=0); containers without CAP_SYS_ADMIN; exhausted user.max_net_namespaces limits on multi-tenant hosts.
Related errors
- mount --make-rshared %s failed: %q
- failed to create namespace: %v
- mount --rbind %s %s failed: %q
- failed to get the current netns: %v
- failed to bind mount ns at %s: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e001b3bff85d1aa7.
Report an issue: GitHub.