windmill-labs/windmill · error
ENABLE_UNSHARE_PID is set but unshare test failed. Error: {}
Error message
ENABLE_UNSHARE_PID is set but unshare test failed.
Error: {}
Flags: {}
Solutions:
• Check if user namespaces are enabled: 'sysctl kernel.unprivileged_userns_clone'
• Check max user namespaces limit: 'cat /proc/sys/user/max_user_namespaces'
(Some AMIs like Bottlerocket have max_user_namespaces=0 which disables user namespaces entirely)
• For Docker: Requires 'privileged: true' in docker-compose for --mount-proc flag
• For Kubernetes: Requires 'privileged: true' in securityContext for --mount-proc flag
• Try different flags via UNSHARE_ISOLATION_FLAGS env var (remove --mount-proc if privileged mode not possible)
• Alternative: Use NSJAIL instead
• Disable: Set ENABLE_UNSHARE_PID=false (or disableUnsharePid=true in Helm chart) What it means
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).
Source
Thrown at backend/windmill-worker/src/worker.rs:474
let test_result = std::process::Command::new("unshare")
.args(&test_cmd_args)
.output();
match test_result {
Ok(output) if output.status.success() => {
if TINI_AVAILABLE.is_some() {
tracing::info!("PID namespace isolation enabled with tini. Flags: {}", flags);
} else {
tracing::info!("PID namespace isolation enabled. Flags: {}", flags);
}
Some("unshare".to_string())
},
Ok(output) => {
let stderr = String::from_utf8_lossy(&output.stderr);
if *ENABLE_UNSHARE_PID {
panic!(
"ENABLE_UNSHARE_PID is set but unshare test failed.\n\
Error: {}\n\
Flags: {}\n\
\n\
Solutions:\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)",
stderr.trim(),
flags
);
}
View on GitHub (pinned to e474e8803c)
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
Example fix
// before (k8s, non-privileged) enabledUnsharePid: true // after: either grant privileges securityContext: privileged: true // or disable the feature enabledUnsharePid: false
Defensive patterns
Strategy: validation
Validate before calling
#!/bin/sh
# preflight check before enabling ENABLE_UNSHARE_PID
sysctl kernel.unprivileged_userns_clone 2>/dev/null || echo 'unprivileged_userns_clone: unknown'
ns=$(cat /proc/sys/user/max_user_namespaces 2>/dev/null || echo 0)
[ "$ns" -gt 0 ] || { echo 'max_user_namespaces=0 — unshare will fail'; exit 1; }
unshare --mount-proc true 2>/dev/null || { echo 'unshare probe failed (need privileged/cap_sys_admin)'; exit 1; } Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- ENABLE_UNSHARE_PID is set but failed to test unshare: {}
- ENABLE_UNSHARE_PID is set but unshare binary not found. Inst
- could not create dir '{directory_path}': {e}
- failed to execute replace_ephemeral command: {}
- sql job on http connection
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/4a5df6053b7cd864.
Report an issue: GitHub.