hashicorp/nomad · error
mount --make-rshared %s failed: %q
Error message
mount --make-rshared %s failed: %q
What it means
NewNS creates a new network namespace and bind-mounts it under /var/run/netns so it persists. Before creating the namespace, it tries to remount the netns directory as shared; if that Mount fails with anything other than EINVAL (meaning the dir is not a mountpoint), the library wraps and returns this error. It indicates the kernel refused the recursive shared remount of /var/run/netns.
Source
Thrown at client/lib/nsutil/netns_linux.go:53
// NewNS creates a new persistent (bind-mounted) network namespace and returns
// an object representing that namespace, without switching to it.
func NewNS(nsName string) (NetNS, error) {
// Create the directory for mounting network namespaces
// This needs to be a shared mountpoint in case it is mounted in to
// other namespaces (containers)
err := os.MkdirAll(NetNSRunDir, 0755)
if err != nil {
return nil, err
}
// Remount the namespace directory shared. This will fail if it is not
// already a mountpoint, so bind-mount it on to itself to "upgrade" it
// to a mountpoint.
err = unix.Mount("", NetNSRunDir, "none", unix.MS_SHARED|unix.MS_REC, "")
if err != nil {
if err != unix.EINVAL {
return nil, fmt.Errorf("mount --make-rshared %s failed: %q", NetNSRunDir, err)
}
// Recursively remount /var/run/netns on itself. The recursive flag is
// so that any existing netns bindmounts are carried over.
err = unix.Mount(NetNSRunDir, NetNSRunDir, "none", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
return nil, fmt.Errorf("mount --rbind %s %s failed: %q", NetNSRunDir, NetNSRunDir, err)
}
// Now we can make it shared
err = unix.Mount("", NetNSRunDir, "none", unix.MS_SHARED|unix.MS_REC, "")
if err != nil {
return nil, fmt.Errorf("mount --make-rshared %s failed: %q", NetNSRunDir, err)
}
}
// create an empty file at the mount pointView on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the process runs with CAP_SYS_ADMIN (e.g. docker run --privileged or add SYS_ADMIN capability) since creating netns requires it
- Verify /var/run/netns exists and is a mountpoint: mkdir -p /var/run/netns && mount --bind /var/run/netns /var/run/netns
- If running in a container, ensure it is not blocked by seccomp/apparmor; use --security-opt seccomp=unconfined for testing
- Check /var/run is a symlink to /run and both paths are consistent
Example fix
// before (inside unprivileged container, fails) ns, err := nsutil.NewNS() // after: grant capability at deploy time // docker run --cap-add SYS_ADMIN -v /run/netns:/run/netns:shared myimage ns, err := nsutil.NewNS()
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat("/run/netns"); err != nil { os.MkdirAll("/run/netns", 0755) }
if err := unix.Mount("", "/run/netns", "", unix.MS_SHARED|unix.MS_REC, ""); err != nil && err != unix.EINVAL {
return fmt.Errorf("environment cannot make /run/netns shared: %v", err)
} Type guard
func canCreateNetns() bool {
return unix.Eaccess == nil // placeholder; check capability instead:
}
func hasCapSysAdmin() bool {
hdr, _ := os.ReadFile("/proc/self/status")
return strings.Contains(string(hdr), "CapEff") && capEnabled(string(hdr))
} Try / catch
ns, err := nsutil.NewNS()
if err != nil && strings.Contains(err.Error(), "make-rshared") {
return fmt.Errorf("netns mount propagation unavailable (need CAP_SYS_ADMIN): %w", err)
} Prevention
- Run namespace-dependent code with CAP_SYS_ADMIN (root or privileged container)
- Pre-mount /run/netns as a shared bind mount in host/container entrypoints
- Smoke-test with 'unshare -n true' before deploying
- Avoid read-only /run in containers that create netns
When it happens
Trigger: unix.Mount("", NetNSRunDir, "none", MS_SHARED|MS_REC) fails with a non-EINVAL error while NewNS runs (invoked via CreateNetwork). Happens when /var/run/netns exists but the mount syscall is rejected for reasons other than 'not a mountpoint' (e.g. EPERM in restricted containers, ENOENT if the dir vanished).
Common situations: Running inside unprivileged containers or sandboxes (Docker without CAP_SYS_ADMIN, gVisor, user-namespace restrictions) where mount() is denied; /var/run/netns removed concurrently; seccomp profiles blocking mount.
Related errors
- mount --rbind %s %s failed: %q
- error from unshare: %v
- failed to bind mount ns at %s: %v
- failed to create namespace: %v
- Failed to unmount proc %q: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/dea7d82b1b5c0067.
Report an issue: GitHub.