jdx/mise · error
bootstrap service '{name}' cannot be both masked and enabled
Error message
bootstrap service '{name}' cannot be both masked and enabled What it means
The second mask-combination check in from_toml_with_origin (src/system/services.rs:232): `masked = true` together with `enabled = true` is rejected. A masked unit is symlinked to /dev/null; enabling it would create a symlink in the wants/ tree pointing at nothing, which is at best noise and at worst a boot-time failure, so the pair is invalid by design.
Source
Thrown at src/system/services.rs:232
}
impl ServiceRequest {
#[cfg(test)]
fn from_toml(name: String, config: ServiceTomlConfig) -> Result<Self> {
Self::from_toml_with_origin(name, config, None)
}
fn from_toml_with_origin(
name: String,
config: ServiceTomlConfig,
origin: Option<ResourceOrigin>,
) -> Result<Self> {
let unit = normalize_unit_name(&name)?;
if config.masked && config.state == ServiceState::Running {
bail!("bootstrap service '{name}' cannot be both masked and running");
}
if config.masked && config.enabled {
bail!("bootstrap service '{name}' cannot be both masked and enabled");
}
Ok(Self {
name,
unit,
state: config.state,
enabled: config.enabled,
masked: config.masked,
on_change: config.on_change,
origin,
inspection: None,
})
}
pub(crate) fn plan(&self) -> ResourcePlan {
let id = ResourceId::new("service", &self.name);
let desired = self.desired();
let Some(inspection) = &self.inspection else {
return self.with_origin(ResourcePlan::new(View on GitHub (pinned to 6f52dcdf99)
Solutions
- For masking: set enabled = false (masking makes enabled moot anyway)
- For enabling: set masked = false
- Check layered configs — one layer may contribute enabled = true while another adds masked = true
- Re-run bootstrap after the flags are mutually consistent
Example fix
# before [bootstrap.services.debug-shell] masked = true enabled = true # -> bail # after [bootstrap.services.debug-shell] masked = true enabled = false
Defensive patterns
Strategy: validation
Validate before calling
# masked + enabled is always invalid — catch it in config lint
python3 - <<'PY'
import tomllib
svc = tomllib.load(open('mise.toml','rb')).get('bootstrap',{}).get('services',{})
if isinstance(svc, dict):
for name, body in svc.items():
if isinstance(body,dict) and body.get('masked') and body.get('enabled'):
print(f"service {name}: masked cannot be enabled")
PY Prevention
- Always write enabled = false next to masked = true to make intent explicit
- When hardening by masking, audit copied templates for leftover enabled = true
- Check layered configs: one layer may inject enabled while another masks
When it happens
Trigger: A service declaration with both `masked = true` and `enabled = true` (enabled defaults may also come into play depending on the config body). Caught during request construction from any config layer.
Common situations: Hardening a machine by masking a service while a copied template still sets enabled = true; enabling a unit and later masking it in another config layer without clearing enabled; defaults merged from a base config producing both flags.
Related errors
- bootstrap service '{name}' cannot be both masked and running
- invalid bootstrap secret name '{name}': use ASCII letters, d
- conflicting bootstrap service declarations for {name}\n\n f
- managed path '{}' notifies unconfigured bootstrap service '{
- managed path '{}' notifies unconfigured bootstrap service '{
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/4f124b267256cd9f.
Report an issue: GitHub.