{"record":{"id":"a07b0d9ecc86f729","repo":"jdx/mise","slug":"service-unit-name-has-invalid-umask-value","errorCode":null,"errorMessage":"service unit '{name}' has invalid `umask` value '{umask}'; expected an octal access mask from 0000 through 0777","messagePattern":"service unit '(.+?)' has invalid `umask` value '(.+?)'; expected an octal access mask from 0000 through 0777","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/systemd.rs","lineNumber":226,"sourceCode":"                && config.on_unit_active_sec.is_none()\n                && config.on_unit_inactive_sec.is_none()\n                && config.on_calendar.is_none()\n            {\n                bail!(\n                    \"timer unit '{name}' must set at least one of `on_boot_sec`, \\\n                     `on_unit_active_sec`, `on_unit_inactive_sec`, or `on_calendar`\"\n                );\n            }\n        }\n        if let Some(nice) = config.nice\n            && !(-20..=19).contains(&nice)\n        {\n            bail!(\"service unit '{name}' has invalid `nice` value {nice}; expected -20 through 19\");\n        }\n        if let Some(umask) = &config.umask\n            && !valid_umask(umask)\n        {\n            bail!(\n                \"service unit '{name}' has invalid `umask` value '{umask}'; expected an octal access mask from 0000 through 0777\"\n            );\n        }\n        let wanted_by = config.wanted_by.unwrap_or_else(|| match kind {\n            SystemdUnitKind::Service => vec![\"default.target\".to_string()],\n            SystemdUnitKind::Timer => vec![\"timers.target\".to_string()],\n        });\n        Ok(Self {\n            unit: format!(\n                \"dev.mise.{name}.{}\",\n                match kind {\n                    SystemdUnitKind::Service => \"service\",\n                    SystemdUnitKind::Timer => \"timer\",\n                }\n            ),\n            name,\n            kind,\n            description: config.description,","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/systemd.rs#L208-L244","documentation":"The optional `umask` for a service unit must be a valid octal access mask from 0000 through 0777; `valid_umask` enforces this at parse time. Invalid values (non-octal digits, out-of-range, wrong format) are rejected before the unit file is generated.","triggerScenarios":"Setting `umask` in a `[systemd.<name>]` service block to a string that fails `valid_umask` — e.g. `\"777\"` (below 0000 range semantics ok but under 4 digits depending on validator), `\"0888\"` (digits 8/9 are not octal), `\"1777\"` (above 0777), or non-numeric text.","commonSituations":"Writing decimal instead of octal (e.g. `umask = \"022\"` is fine but `umask = \"22\"` or `\"18\"` is not); including a leading mode digit above 7; typos copying umask from shell docs.","solutions":["Write the umask as a 4-digit octal string in 0000..0777, e.g. `umask = \"0022\"`.","Remove non-octal digits (no 8 or 9 allowed).","Remove the `umask` key to use the systemd default."],"exampleFix":"# before\n[systemd.myapp]\nexec_start = \"/usr/bin/myapp\"\numask = \"0888\"\n\n# after\n[systemd.myapp]\nexec_start = \"/usr/bin/myapp\"\numask = \"0022\"","handlingStrategy":"validation","validationCode":"fn valid_umask(s: &str) -> bool {\n    s.len() == 4 && s.chars().all(|c| ('0'..='7').contains(&c))\n        && s <= \"0777\"\n}\nassert!(valid_umask(\"0022\") && !valid_umask(\"0888\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write umask as a 4-digit octal string (e.g. \"0022\").","Remember octal digits only go 0-7.","Validate umask strings at config-generation time, not deploy time."],"tags":["systemd","validation","umask","octal"],"backgroundTag":"invalid-config-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}