{"record":{"id":"4a5df6053b7cd864","repo":"windmill-labs/windmill","slug":"enable-unshare-pid-is-set-but-unshare-test-failed","errorCode":null,"errorMessage":"ENABLE_UNSHARE_PID is set but unshare test failed.\nError: {}\nFlags: {}\n\nSolutions:\n• Check if user namespaces are enabled: 'sysctl kernel.unprivileged_userns_clone'\n• Check max user namespaces limit: 'cat /proc/sys/user/max_user_namespaces'\n  (Some AMIs like Bottlerocket have max_user_namespaces=0 which disables user namespaces entirely)\n• For Docker: Requires 'privileged: true' in docker-compose for --mount-proc flag\n• For Kubernetes: Requires 'privileged: true' in securityContext for --mount-proc flag\n• Try different flags via UNSHARE_ISOLATION_FLAGS env var (remove --mount-proc if privileged mode not possible)\n• Alternative: Use NSJAIL instead\n• Disable: Set ENABLE_UNSHARE_PID=false (or disableUnsharePid=true in Helm chart)","messagePattern":"ENABLE_UNSHARE_PID is set but unshare test failed\\.\nError: \\{\\}\nFlags: \\{\\}\n\nSolutions:\n• Check if user namespaces are enabled: 'sysctl kernel\\.unprivileged_userns_clone'\n• Check max user namespaces limit: 'cat /proc/sys/user/max_user_namespaces'\n  \\(Some AMIs like Bottlerocket have max_user_namespaces=0 which disables user namespaces entirely\\)\n• For Docker: Requires 'privileged: true' in docker-compose for --mount-proc flag\n• For Kubernetes: Requires 'privileged: true' in securityContext for --mount-proc flag\n• Try different flags via UNSHARE_ISOLATION_FLAGS env var \\(remove --mount-proc if privileged mode not possible\\)\n• Alternative: Use NSJAIL instead\n• Disable: Set ENABLE_UNSHARE_PID=false \\(or disableUnsharePid=true in Helm chart\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-worker/src/worker.rs","lineNumber":474,"sourceCode":"\n        let test_result = std::process::Command::new(\"unshare\")\n            .args(&test_cmd_args)\n            .output();\n\n        match test_result {\n            Ok(output) if output.status.success() => {\n                if TINI_AVAILABLE.is_some() {\n                    tracing::info!(\"PID namespace isolation enabled with tini. Flags: {}\", flags);\n                } else {\n                    tracing::info!(\"PID namespace isolation enabled. Flags: {}\", flags);\n                }\n                Some(\"unshare\".to_string())\n            },\n            Ok(output) => {\n                let stderr = String::from_utf8_lossy(&output.stderr);\n\n                if *ENABLE_UNSHARE_PID {\n                    panic!(\n                        \"ENABLE_UNSHARE_PID is set but unshare test failed.\\n\\\n                        Error: {}\\n\\\n                        Flags: {}\\n\\\n                        \\n\\\n                        Solutions:\\n\\\n                        • Check if user namespaces are enabled: 'sysctl kernel.unprivileged_userns_clone'\\n\\\n                        • Check max user namespaces limit: 'cat /proc/sys/user/max_user_namespaces'\\n\\\n                          (Some AMIs like Bottlerocket have max_user_namespaces=0 which disables user namespaces entirely)\\n\\\n                        • For Docker: Requires 'privileged: true' in docker-compose for --mount-proc flag\\n\\\n                        • For Kubernetes: Requires 'privileged: true' in securityContext for --mount-proc flag\\n\\\n                        • Try different flags via UNSHARE_ISOLATION_FLAGS env var (remove --mount-proc if privileged mode not possible)\\n\\\n                        • Alternative: Use NSJAIL instead\\n\\\n                        • Disable: Set ENABLE_UNSHARE_PID=false (or disableUnsharePid=true in Helm chart)\",\n                        stderr.trim(),\n                        flags\n                    );\n                }\n","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/worker.rs#L456-L492","documentation":"When ENABLE_UNSHARE_PID is enabled, Windmill workers isolate job processes into a PID namespace by invoking the `unshare` binary. At startup it runs a probe test; if the probe spawns but fails (non-success exit, checked via stderr output), and the setting is required, the worker panics with a diagnostic listing kernel userns settings, container privilege requirements, and alternatives (NSJAIL, disabling the feature).","triggerScenarios":"ENABLE_UNSHARE_PID=true (or disableUnsharePid=false in Helm) while the probe `unshare --mount-proc ...` fails: user namespaces disabled (max_user_namespaces=0, userns_clone=0), unprivileged userns restricted, or --mount-proc rejected because the container lacks CAP_SYS_ADMIN (non-privileged Docker/K8s).","commonSituations":"Bottlerocket/Amazon Linux AMIs with max_user_namespaces=0; Kubernetes pod without `privileged: true` securityContext; Docker compose without privileged/required capabilities; hardened kernels with unprivileged_userns_clone=0.","solutions":["Set ENABLE_UNSHARE_PID=false (or disableUnsharePid=true in Helm) if PID isolation is not strictly needed","Check `sysctl kernel.unprivileged_userns_clone` and `cat /proc/sys/user/max_user_namespaces`; raise max_user_namespaces (e.g. sysctl -w user.max_user_namespaces=15000)","Run the container with `privileged: true` (docker-compose / k8s securityContext) so --mount-proc works","Adjust UNSHARE_ISOLATION_FLAGS env var to drop --mount-proc if privilege cannot be granted","Switch to NSJAIL isolation as an alternative"],"exampleFix":"// before (k8s, non-privileged)\nenabledUnsharePid: true\n// after: either grant privileges\nsecurityContext:\n  privileged: true\n// or disable the feature\nenabledUnsharePid: false","handlingStrategy":"validation","validationCode":"#!/bin/sh\n# preflight check before enabling ENABLE_UNSHARE_PID\nsysctl kernel.unprivileged_userns_clone 2>/dev/null || echo 'unprivileged_userns_clone: unknown'\nns=$(cat /proc/sys/user/max_user_namespaces 2>/dev/null || echo 0)\n[ \"$ns\" -gt 0 ] || { echo 'max_user_namespaces=0 — unshare will fail'; exit 1; }\nunshare --mount-proc true 2>/dev/null || { echo 'unshare probe failed (need privileged/cap_sys_admin)'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the unshare probe as a startup/preflight check before enabling the feature","Set user.max_user_namespaces>0 on hosts (Bottlerocket/AL2 need explicit config)","Grant privileged:true only when PID isolation is required","Document the UNSHARE_ISOLATION_FLAGS fallback per environment"],"tags":["rust","worker","isolation","unshare","linux"],"backgroundTag":"unshare-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}