{"record":{"id":"e57d23881a9ab73f","repo":"hashicorp/nomad","slug":"unable-to-convert-userid-to-uint32-w","errorCode":null,"errorMessage":"unable to convert userid to uint32: %w","messagePattern":"unable to convert userid to uint32: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/shared/executor/executor_unix.go","lineNumber":86,"sourceCode":"\tgidStrings, err := u.GroupIds()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to lookup user's group membership: %v\", err)\n\t}\n\n\tgids := make([]uint32, len(gidStrings))\n\tfor _, gidString := range gidStrings {\n\t\tu, err := strconv.ParseUint(gidString, 10, 32)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to convert user's group to uint32 %s: %v\", gidString, err)\n\t\t}\n\n\t\tgids = append(gids, uint32(u))\n\t}\n\n\t// Convert the uid and gid\n\tuid, err := strconv.ParseUint(u.Uid, 10, 32)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to convert userid to uint32: %w\", err)\n\t}\n\tgid, err := strconv.ParseUint(u.Gid, 10, 32)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to convert groupid to uint32: %s\", err)\n\t}\n\n\t// Set the command to run as that user and group.\n\tif cmd.SysProcAttr == nil {\n\t\tcmd.SysProcAttr = &syscall.SysProcAttr{}\n\t}\n\tif cmd.SysProcAttr.Credential == nil {\n\t\tcmd.SysProcAttr.Credential = &syscall.Credential{}\n\t}\n\tcmd.SysProcAttr.Credential.Uid = uint32(uid)\n\tcmd.SysProcAttr.Credential.Gid = uint32(gid)\n\tcmd.SysProcAttr.Credential.Groups = gids\n\n\t// Override USER, LOGNAME, and HOME environment variables.","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/shared/executor/executor_unix.go#L68-L104","documentation":"After group setup, setCmdUser converts the resolved user's u.Uid string to uint32 with strconv.ParseUint so it can be placed in syscall.Credential. A failure here means the user database returned a uid that is not a valid 32-bit unsigned integer; the parse error is wrapped with %w so callers can inspect it.","triggerScenarios":"u.Uid (from users.Lookup) is empty, non-numeric, or >4294967295 — e.g. a broken NSS backend returning malformed passwd entries.","commonSituations":"LDAP passwd entries with malformed uidNumber; corrupted /etc/passwd line for the task user; custom NSS module returning bad data.","solutions":["Check 'getent passwd <userid>' output and confirm the uid field is a valid numeric uid < 4294967296.","Fix the offending /etc/passwd line or LDAP uidNumber attribute.","Re-create the user with a sane uid (e.g. 'useradd -u 1005 appuser')."],"exampleFix":"// before (/etc/passwd)\nappuser:x:abc:1005::/home/appuser:/bin/false\n// after\nappuser:x:1005:1005::/home/appuser:/bin/false","handlingStrategy":"validation","validationCode":"// Go: verify uid is numeric before launching\nu, err := user.Lookup(taskUser)\nif err != nil {\n    return err\n}\nif _, err := strconv.ParseUint(u.Uid, 10, 32); err != nil {\n    return fmt.Errorf(\"user %q has malformed uid %q\", taskUser, u.Uid)\n}","typeGuard":"func hasValidUid(u *user.User) bool {\n    _, err := strconv.ParseUint(u.Uid, 10, 32)\n    return err == nil\n}","tryCatchPattern":"if err := exec.SetUser(cmd, userid); err != nil {\n    var perr *strconv.NumError\n    if errors.As(err, &perr) {\n        return fmt.Errorf(\"bad numeric id from user db: %w\", err)\n    }\n    return err\n}","preventionTips":["Never hand-edit /etc/passwd; use useradd/usermod.","Enforce numeric uidNumber/gidNumber schemas in LDAP.","Include 'getent passwd <taskuser>' checks in client preflight."],"tags":["unix","uid","strconv","nomad-executor"],"backgroundTag":"invalid-numeric-id","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}