{"record":{"id":"dea7d82b1b5c0067","repo":"hashicorp/nomad","slug":"mount-make-rshared-s-failed-q","errorCode":null,"errorMessage":"mount --make-rshared %s failed: %q","messagePattern":"mount --make-rshared (.+?) failed: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/lib/nsutil/netns_linux.go","lineNumber":53,"sourceCode":"// NewNS creates a new persistent (bind-mounted) network namespace and returns\n// an object representing that namespace, without switching to it.\nfunc NewNS(nsName string) (NetNS, error) {\n\n\t// Create the directory for mounting network namespaces\n\t// This needs to be a shared mountpoint in case it is mounted in to\n\t// other namespaces (containers)\n\terr := os.MkdirAll(NetNSRunDir, 0755)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Remount the namespace directory shared. This will fail if it is not\n\t// already a mountpoint, so bind-mount it on to itself to \"upgrade\" it\n\t// to a mountpoint.\n\terr = unix.Mount(\"\", NetNSRunDir, \"none\", unix.MS_SHARED|unix.MS_REC, \"\")\n\tif err != nil {\n\t\tif err != unix.EINVAL {\n\t\t\treturn nil, fmt.Errorf(\"mount --make-rshared %s failed: %q\", NetNSRunDir, err)\n\t\t}\n\n\t\t// Recursively remount /var/run/netns on itself. The recursive flag is\n\t\t// so that any existing netns bindmounts are carried over.\n\t\terr = unix.Mount(NetNSRunDir, NetNSRunDir, \"none\", unix.MS_BIND|unix.MS_REC, \"\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"mount --rbind %s %s failed: %q\", NetNSRunDir, NetNSRunDir, err)\n\t\t}\n\n\t\t// Now we can make it shared\n\t\terr = unix.Mount(\"\", NetNSRunDir, \"none\", unix.MS_SHARED|unix.MS_REC, \"\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"mount --make-rshared %s failed: %q\", NetNSRunDir, err)\n\t\t}\n\n\t}\n\n\t// create an empty file at the mount point","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/lib/nsutil/netns_linux.go#L35-L71","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before (inside unprivileged container, fails)\nns, err := nsutil.NewNS()\n// after: grant capability at deploy time\n// docker run --cap-add SYS_ADMIN -v /run/netns:/run/netns:shared myimage\nns, err := nsutil.NewNS()","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(\"/run/netns\"); err != nil { os.MkdirAll(\"/run/netns\", 0755) }\nif err := unix.Mount(\"\", \"/run/netns\", \"\", unix.MS_SHARED|unix.MS_REC, \"\"); err != nil && err != unix.EINVAL {\n    return fmt.Errorf(\"environment cannot make /run/netns shared: %v\", err)\n}","typeGuard":"func canCreateNetns() bool {\n    return unix.Eaccess == nil // placeholder; check capability instead:\n}\nfunc hasCapSysAdmin() bool {\n    hdr, _ := os.ReadFile(\"/proc/self/status\")\n    return strings.Contains(string(hdr), \"CapEff\") && capEnabled(string(hdr))\n}","tryCatchPattern":"ns, err := nsutil.NewNS()\nif err != nil && strings.Contains(err.Error(), \"make-rshared\") {\n    return fmt.Errorf(\"netns mount propagation unavailable (need CAP_SYS_ADMIN): %w\", err)\n}","preventionTips":["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"],"tags":["linux","network-namespace","mount","privileges"],"backgroundTag":"mount-permission-denied","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}