hashicorp/nomad · error

unable to convert groupid to uint32: %s

Error message

unable to convert groupid to uint32: %s

What it means

setCmdUser converts the resolved user's u.Gid string to uint32 for syscall.Credential. If the gid string from the user lookup is not parseable as a 32-bit unsigned integer, this error is returned (note: formatted with %s rather than %w, so it is not unwrappable).

Source

Thrown at drivers/shared/executor/executor_unix.go:90

	gids := make([]uint32, len(gidStrings))
	for _, gidString := range gidStrings {
		u, err := strconv.ParseUint(gidString, 10, 32)
		if err != nil {
			return fmt.Errorf("unable to convert user's group to uint32 %s: %v", gidString, err)
		}

		gids = append(gids, uint32(u))
	}

	// Convert the uid and gid
	uid, err := strconv.ParseUint(u.Uid, 10, 32)
	if err != nil {
		return fmt.Errorf("unable to convert userid to uint32: %w", err)
	}
	gid, err := strconv.ParseUint(u.Gid, 10, 32)
	if err != nil {
		return fmt.Errorf("unable to convert groupid to uint32: %s", err)
	}

	// Set the command to run as that user and group.
	if cmd.SysProcAttr == nil {
		cmd.SysProcAttr = &syscall.SysProcAttr{}
	}
	if cmd.SysProcAttr.Credential == nil {
		cmd.SysProcAttr.Credential = &syscall.Credential{}
	}
	cmd.SysProcAttr.Credential.Uid = uint32(uid)
	cmd.SysProcAttr.Credential.Gid = uint32(gid)
	cmd.SysProcAttr.Credential.Groups = gids

	// Override USER, LOGNAME, and HOME environment variables.
	cmd.Env = append(cmd.Env, fmt.Sprintf("USER=%s", u.Username))
	cmd.Env = append(cmd.Env, fmt.Sprintf("LOGNAME=%s", u.Username))
	cmd.Env = append(cmd.Env, fmt.Sprintf("HOME=%s", u.HomeDir))

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect 'getent passwd <userid>' and validate the gid field is numeric and < 4294967296.
  2. Fix /etc/passwd or the LDAP gidNumber attribute for the user.
  3. Re-create the user with a valid primary gid.

Example fix

// before (/etc/passwd)
appuser:x:1005:gid::/home/appuser:/bin/false
// after
appuser:x:1005:1005::/home/appuser:/bin/false
Defensive patterns

Strategy: validation

Validate before calling

// Go: verify gid is numeric before launching
u, err := user.Lookup(taskUser)
if err != nil {
    return err
}
if _, err := strconv.ParseUint(u.Gid, 10, 32); err != nil {
    return fmt.Errorf("user %q has malformed gid %q", taskUser, u.Gid)
}

Type guard

func hasValidGid(u *user.User) bool {
    _, err := strconv.ParseUint(u.Gid, 10, 32)
    return err == nil
}

Try / catch

if err := exec.SetUser(cmd, userid); err != nil {
    if strings.Contains(err.Error(), "groupid to uint32") {
        // passwd gid field corrupt: remediate user db
    }
    return err
}

Prevention

When it happens

Trigger: u.Gid returned by users.Lookup is empty, non-numeric, or exceeds uint32 — malformed passwd/group data from NSS/LDAP.

Common situations: LDAP gidNumber missing or malformed; hand-edited /etc/passwd with bad gid field; broken custom NSS module.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/025c6fbc573cda32. Report an issue: GitHub.