{"record":{"id":"327ab2bc16569e6b","repo":"windmill-labs/windmill","slug":"failed-to-set-permissions-to-e","errorCode":null,"errorMessage":"Failed to set permissions to {}: {e}","messagePattern":"Failed to set permissions to (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/worker.rs","lineNumber":958,"sourceCode":"    job_dir: &str,\n    user_defined_path: &str,\n    content: &str,\n    mode: Option<u32>,\n) -> error::Result<PathBuf> {\n    let normalized_full_path = is_allowed_file_location(job_dir, user_defined_path)?;\n\n    let full_path = normalized_full_path.as_path();\n    if let Some(parent_dir) = full_path.parent() {\n        std::fs::create_dir_all(parent_dir)?;\n    }\n\n    let mut file = File::create(full_path)?;\n\n    #[cfg(unix)]\n    if let Some(mode) = mode {\n        let perm = std::os::unix::fs::PermissionsExt::from_mode(mode);\n        file.set_permissions(perm)\n            .map_err(|e| anyhow!(\"Failed to set permissions to {}: {e}\", user_defined_path))?;\n    }\n\n    #[cfg(windows)]\n    if mode.is_some() {\n        tracing::error!(\"Cannot use `mode` to set file permissions on windows workers\");\n    }\n\n    file.write_all(content.as_bytes())?;\n    file.flush()?;\n    Ok(normalized_full_path)\n}\n\npub async fn reload_custom_tags_setting(db: &DB) -> error::Result<()> {\n    let q =\n        crate::global_settings::load_value_from_global_settings(db, CUSTOM_TAGS_SETTING).await?;\n    apply_custom_tags_setting(q);\n    Ok(())\n}","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/worker.rs#L940-L976","documentation":"Raised in write_file_at_user_defined_location when File::set_permissions fails after creating the file at the user-defined path inside the job directory. The unix branch converts the requested numeric mode via PermissionsExt::from_mode and applies it; an OS-level chmod failure (e.g. EPERM) produces this error, wrapping the original io::Error message with the path.","triggerScenarios":"A job writes a file (via create_file_resources) with an explicit `mode` (permission bits) on a unix worker, and chmod on the just-created file fails: filesystem doesn't support permissions, immutable file/dir, ACL/SELinux denial, or ownership quirks on mounted volumes.","commonSituations":"Job directory on a filesystem without unix permission support (some NFS mounts, certain overlay/container volumes, CIFS/SMB shares); AppArmor/SELinux policy blocking chmod; read-only remount; running in a container where the mount strips capability to change modes.","solutions":["Check the wrapped io::Error detail in the message (EPERM/EACCES/EINVAL etc.) to identify the cause.","Confirm the job directory filesystem supports unix permission bits (avoid SMB/CIFS or restricted NFS mounts for the worker run dir).","Verify no SELinux/AppArmor policy denies chmod in the worker container/host.","Drop or adjust the `mode` argument so the file keeps default permissions if the environment cannot honor it."],"exampleFix":"// before\nlet path = write_file_at_user_defined_location(job_dir, \"run.sh\", content, Some(0o755))?;\n// after\nlet path = match write_file_at_user_defined_location(job_dir, \"run.sh\", content, Some(0o755)) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"Failed to set permissions\") => {\n        tracing::warn!(\"chmod unsupported on this volume; writing without explicit mode\");\n        write_file_at_user_defined_location(job_dir, \"run.sh\", content, None)?\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":"// Pre-check the target volume supports chmod before requesting a mode\nuse std::os::unix::fs::PermissionsExt;\nlet probe = std::path::Path::new(job_dir).join(\".perm_probe\");\nstd::fs::write(&probe, b\"\")?;\nlet ok = std::fs::set_permissions(&probe, std::fs::Permissions::from_mode(0o600)).is_ok();\nlet _ = std::fs::remove_file(&probe);\nif !ok && mode.is_some() {\n    eprintln!(\"filesystem does not honor chmod; mode will be ignored\");\n}","typeGuard":null,"tryCatchPattern":"match write_file_at_user_defined_location(job_dir, path, content, Some(0o755)) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"Failed to set permissions\") => {\n        // chmod unsupported on this volume; fall back to default perms\n        write_file_at_user_defined_location(job_dir, path, content, None)?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Place worker job directories on filesystems that support unix permission bits (ext4/xfs, not SMB/CIFS).","Check container/SELinux/AppArmor policies permit chmod in the job directory.","Avoid mounting the job dir read-only or with mode-stripping options.","Only pass an explicit `mode` when the environment actually needs it; default perms suffice in most cases.","Catch the \"Failed to set permissions\" prefix and degrade gracefully rather than failing the whole job."],"tags":["filesystem","permissions","unix","worker","rust"],"backgroundTag":"chmod-permission-denied","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}