jdx/mise · error

bootstrap user ' ' requires undeclared group

Error message

bootstrap user '{}' requires undeclared group '{group}'

What it means

A bootstrap user references a group (via group or groups) that is neither declared in the bootstrap groups config nor present on the system (nix Group::from_name returns None). mise refuses to proceed because useradd/usermod would fail joining a nonexistent group.

Solutions

  1. Add a [[bootstrap.groups]] entry with state="present" for the referenced group.
  2. Fix the group name typo if it should match an existing/declared group.
  3. Create the group on the system manually if it is managed outside mise bootstrap.

Example fix

// before
[[bootstrap.users]]
name = "ci"
groups = ["docker"]

// after
[[bootstrap.groups]]
name = "docker"
state = "present"
[[bootstrap.users]]
name = "ci"
groups = ["docker"]
Defensive patterns

Strategy: validation

Validate before calling

function validateGroupExists(config) {
  const declared = new Set(config.groups.map((g) => g.name));
  for (const u of config.users) {
    for (const g of [u.group, ...(u.groups || [])].filter(Boolean)) {
      if (!declared.has(g)) {
        console.warn(`user '${u.name}' group '${g}' is undeclared; ensure it exists on the host`);
      }
    }
  }
}

Try / catch

try {
  await mise.bootstrap.apply(config);
} catch (e) {
  if (String(e).includes('requires undeclared group')) {
    console.error('Declare the group in bootstrap config or create it on the host:', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: user.groups contains a group name with no [[bootstrap.groups]] declaration and no such group existing on the machine.

Common situations: Typo in a group name; expecting a group created by another tool (ansible, puppet) that hasn't run; declaring users before the groups they need in the config.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/1935287f36c814fd. Report an issue: GitHub.

Appendix: source

Thrown at src/system/accounts.rs:613

        .iter()
        .map(|group| (group.name.as_str(), group.state))
        .collect::<IndexMap<_, _>>();
    for user in users
        .iter()
        .filter(|user| user.state == AccountState::Present)
    {
        for group in user
            .group
            .iter()
            .chain(user.groups.iter().flat_map(|groups| groups.iter()))
        {
            match managed_groups.get(group.as_str()) {
                Some(AccountState::Absent) => bail!(
                    "bootstrap user '{}' requires group '{group}', but that group is absent",
                    user.name
                ),
                Some(AccountState::Present) => {}
                None if nix::unistd::Group::from_name(group)?.is_none() => bail!(
                    "bootstrap user '{}' requires undeclared group '{group}'",
                    user.name
                ),
                None => {}
            }
        }
    }
    Ok(())
}

fn inspect_user(name: &str, desired_uid: Option<u32>) -> Result<UserInspection> {
    let Some(user) = nix::unistd::User::from_name(name)? else {
        return match desired_uid {
            Some(uid) => match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(uid))? {
                Some(user) => Ok(UserInspection::IdCollision {
                    uid,
                    name: user.name,
                }),

View on GitHub (pinned to 533346cc37)