jdx/mise · error

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

Error message

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

What it means

The other arm of the group-reference check: a present user references a group that is not managed in [bootstrap.groups] (absent from the managed map) and also does not exist on the system (nix::unistd::Group::from_name returns None). mise would otherwise create a user pointing at a nonexistent primary/supplementary group, so validation fails and names both the user and the undeclared group.

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 9dcfcaa0dc)

Solutions

  1. Declare the group in config: add [bootstrap.groups.<name>] with state = "present" so mise creates it before the user.
  2. If the group should already exist on the host, fix the host (create it) or fix the typo in the user's group/groups reference.
  3. Use an existing system group intentionally (e.g. "users") if that is the correct parent.

Example fix

# before
[bootstrap.users.deploy]
state = "present"
group = "deploy"   # no such group on host or in config
# after
[bootstrap.users.deploy]
state = "present"
group = "deploy"

[bootstrap.groups.deploy]
state = "present"
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
# every group referenced by a present user must be managed or already exist
while read -r g; do
  grep -q "^\[bootstrap\.groups\.$g\]" mise.toml 2>/dev/null || getent group "$g" >/dev/null || {
    echo "undeclared group: $g" >&2; exit 1;
  }
done < <(awk '/^\[bootstrap\.users\./{u=1} /^group = /{if(u) print $3} /^\[/{u=0}' mise.toml | tr -d '"')

Type guard

import grp

def group_exists(name: str) -> bool:
    try:
        grp.getgrnam(name)
        return True
    except KeyError:
        return False

def user_groups_available(user: dict, managed: set, exists=group_exists) -> bool:
    refs = ([user['group']] if 'group' in user else []) + list(user.get('groups', []))
    return all(g in managed or exists(g) for g in refs)

Prevention

When it happens

Trigger: A present user with group = "release" or groups = ["release"] where [bootstrap.groups.release] is not defined in any config layer and the host has no 'release' group in /etc/group. Managed groups set to present pass; existing system groups (e.g. "users") also pass.

Common situations: Typos in group names; assuming a distro group exists on a minimal image; forgetting to declare in config a group that only exists on some hosts; fresh containers where the base image lacks the expected group.

Related errors


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