{"record":{"id":"a02e62b8514d428b","repo":"jdx/mise","slug":"bootstrap-service-name-cannot-be-both-masked-a","errorCode":null,"errorMessage":"bootstrap service '{name}' cannot be both masked and running","messagePattern":"bootstrap service '(.+?)' cannot be both masked and running","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/services.rs","lineNumber":229,"sourceCode":"    for request in requests {\n        request.inspection = Some(inspect_service(&systemctl, &request.unit));\n    }\n}\n\nimpl ServiceRequest {\n    #[cfg(test)]\n    fn from_toml(name: String, config: ServiceTomlConfig) -> Result<Self> {\n        Self::from_toml_with_origin(name, config, None)\n    }\n\n    fn from_toml_with_origin(\n        name: String,\n        config: ServiceTomlConfig,\n        origin: Option<ResourceOrigin>,\n    ) -> Result<Self> {\n        let unit = normalize_unit_name(&name)?;\n        if config.masked && config.state == ServiceState::Running {\n            bail!(\"bootstrap service '{name}' cannot be both masked and running\");\n        }\n        if config.masked && config.enabled {\n            bail!(\"bootstrap service '{name}' cannot be both masked and enabled\");\n        }\n        Ok(Self {\n            name,\n            unit,\n            state: config.state,\n            enabled: config.enabled,\n            masked: config.masked,\n            on_change: config.on_change,\n            origin,\n            inspection: None,\n        })\n    }\n\n    pub(crate) fn plan(&self) -> ResourcePlan {\n        let id = ResourceId::new(\"service\", &self.name);","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/services.rs#L211-L247","documentation":"When building a ServiceRequest from TOML (from_toml_with_origin, src/system/services.rs:229), mise rejects the combination masked = true and state = \"running\": a masked unit's binary is symlinked to /dev/null, so systemd cannot start it — the desired state is unsatisfiable by construction.","triggerScenarios":"Declaring a service with `masked = true` together with `state = \"running\"` in any bootstrap config layer. Validated at request-construction time, before the plan or systemctl runs.","commonSituations":"Copy-pasting a service block and toggling masked for a 'disable it' use case without changing state; merging two config fragments that together set both fields; misunderstanding masked as a softer version of disabled.","solutions":["If the service must be masked: set its state to stopped (or omit state) — masking already guarantees it cannot run","If the service must run: set masked = false (and optionally enabled = true)","If you only wanted it disabled at boot: use enabled = false instead of masked","Re-run bootstrap; the request builds and planning proceeds"],"exampleFix":"# before\n[bootstrap.services.telnet]\nmasked = true\nstate = \"running\"   # -> bail\n# after\n[bootstrap.services.telnet]\nmasked = true\nstate = \"stopped\"","handlingStrategy":"validation","validationCode":"# masked + running is always invalid — catch it in config lint\npython3 - <<'PY'\nimport tomllib\nsvc = tomllib.load(open('mise.toml','rb')).get('bootstrap',{}).get('services',{})\nif isinstance(svc, dict):\n    for name, body in svc.items():\n        if isinstance(body,dict) and body.get('masked') and body.get('state')=='running':\n            print(f\"service {name}: masked cannot be running\")\nPY","typeGuard":null,"tryCatchPattern":null,"preventionTips":["masked means cannot run — pair it with state = \"stopped\" or omit state","Use enabled = false for boot-time disablement; reserve masked for hard-blocking a unit","Lint masked/state/enabled combinations in CI over all config layers"],"tags":["bootstrap","services","systemd","validation","config","mise"],"backgroundTag":"invalid-config-combination","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}