jdx/mise · error
managed system files require owner '{owner}', but that boots
Error message
managed system files require owner '{owner}', but that bootstrap user is absent What it means
Raised during cross-resource validation when a managed file declares an `owner` that is also declared as a bootstrap user with state = "absent". Setting ownership requires the user to exist, but the bootstrap plan explicitly removes that user — the plan is contradictory, so convergence is refused.
Source
Thrown at src/system/managed_files.rs:859
accounts: Option<&super::accounts::AccountRequests>,
allow_pending_accounts: bool,
) -> Result<()> {
for (owner, group) in files
.iter()
.filter(|request| request.state == ManagedState::Present)
.map(|request| (request.owner.as_deref(), request.group.as_deref()))
.chain(
directories
.iter()
.filter(|request| request.state == ManagedState::Present)
.map(|request| (request.owner.as_deref(), request.group.as_deref())),
)
{
if let Some(owner) = owner {
match accounts
.and_then(|accounts| accounts.users.iter().find(|request| request.name == owner))
{
Some(request) if request.state == super::accounts::AccountState::Absent => bail!(
"managed system files require owner '{owner}', but that bootstrap user is absent"
),
Some(request)
if allow_pending_accounts
&& request.plan().action == ResourceAction::Unknown =>
{
bail!(
"managed system files require owner '{owner}', but that bootstrap user cannot be safely converged"
)
}
Some(_) if allow_pending_accounts => {}
Some(_) | None => {
resolve_user(owner)?;
}
}
}
if let Some(group) = group {
match accountsView on GitHub (pinned to afd2eddd3a)
Solutions
- Remove the account-absent declaration so the owner user is not being deleted.
- Or change the file entry's `owner` to a user that exists or is declared state = "present".
- Or drop the `owner` from the file entry if default ownership is acceptable.
- If the account is being retired, also retire or re-own its file entries in the same config change.
Example fix
# before [[bootstrap.files]] path = "/etc/app.conf" owner = "svc-app" state = "present" [[bootstrap.users]] name = "svc-app" state = "absent" # after [[bootstrap.files]] path = "/etc/app.conf" owner = "svc-app" state = "present" [[bootstrap.users]] name = "svc-app" state = "present"
Defensive patterns
Strategy: validation
Validate before calling
fn validate_owner_accounts(files: &[ManagedFileRequest], users: &[UserRequest]) -> Result<(), String> {
for f in files {
if let Some(owner) = &f.owner {
if users.iter().any(|u| &u.name == owner && u.state == AccountState::Absent) {
return Err(format!("owner '{}' is declared absent by bootstrap", owner));
}
}
}
Ok(())
} Prevention
- Cross-check every file `owner` against account entries in the same config.
- When retiring a user, update or remove all file entries referencing it in the same change.
- Keep an automated config check that no absent account is referenced as an owner/group.
When it happens
Trigger: Converging bootstrap where a [bootstrap.files] entry has owner = "<name>" and a bootstrap account entry for the same name has state = "absent"; validation searches accounts.users for the owner and matches the Absent arm.
Common situations: A user was renamed in the config (old user set absent, new files entry still referencing the old name); a cleanup config removes an account but leftover file entries still reference it; copy-paste between host configs where one host retires the account.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- managed system files require owner '{owner}', but that boots
- present bootstrap user '{name}' requires a primary group
- present bootstrap user '{name}' must not set remove_home
- absent bootstrap user '{name}' may only set state and remove
- bootstrap user '{name}' sets exclusive_groups without groups
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/832717913f6810e4.
Report an issue: GitHub.