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 accounts

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Remove the account-absent declaration so the owner user is not being deleted.
  2. Or change the file entry's `owner` to a user that exists or is declared state = "present".
  3. Or drop the `owner` from the file entry if default ownership is acceptable.
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/832717913f6810e4. Report an issue: GitHub.