{"record":{"id":"239f19dfc7fbd7d7","repo":"hashicorp/nomad","slug":"error-parsing-gid-w","errorCode":null,"errorMessage":"error parsing gid: %w","messagePattern":"error parsing gid: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/users/lookup.go","lineNumber":44,"sourceCode":"\n// LookupUnix returns the UID, GID, and home directory for username or returns\n// an error. ID values are int to work well with Go library functions.\n//\n// Will always fail on Windows and Plan 9.\nfunc LookupUnix(username string) (int, int, string, error) {\n\tu, err := Lookup(username)\n\tif err != nil {\n\t\treturn 0, 0, \"\", fmt.Errorf(\"error looking up user %q: %w\", username, err)\n\t}\n\n\tuid, err := strconv.Atoi(u.Uid)\n\tif err != nil {\n\t\treturn 0, 0, \"\", fmt.Errorf(\"error parsing uid: %w\", err)\n\t}\n\n\tgid, err := strconv.Atoi(u.Gid)\n\tif err != nil {\n\t\treturn 0, 0, \"\", fmt.Errorf(\"error parsing gid: %w\", err)\n\t}\n\n\treturn uid, gid, u.HomeDir, nil\n}\n\n// lock is used to serialize all user lookup at the process level, because\n// some NSS implementations are not concurrency safe\nvar lock sync.Mutex\n\n// internalLookupUser username while holding a global process lock.\nfunc internalLookupUser(username string) (*user.User, error) {\n\tlock.Lock()\n\tdefer lock.Unlock()\n\treturn user.Lookup(username)\n}\n\n// Current returns the current user, acquired while holding a global process\n// lock.","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/users/lookup.go#L26-L62","documentation":"Fires in LookupUnix when the group ID returned by the OS user database cannot be parsed as an integer — the system's passwd/group source (e.g. LDAP or NSS) returned a non-numeric GID for the user.","triggerScenarios":"Calling users.LookupUnix for a user whose group id field is non-numeric — bad /etc/passwd gid column, or an NSS/LDAP source returning invalid gidNumber.","commonSituations":"Manual /etc/passwd edits with a typo in the gid column; LDAP/SSSD entries with malformed gidNumber; provisioning scripts writing corrupt entries.","solutions":["Fix the gid column for the user in /etc/passwd (must be a number)","Correct gidNumber in the LDAP/NSS directory source if centralized","Recreate the user with standard tooling to regenerate valid entries"],"exampleFix":"// before\nsvc:x:1000:admin   # non-numeric gid\n// after\nsvc:x:1000:1000    # numeric gid","handlingStrategy":"validation","validationCode":"u, err := user.Lookup(username)\nif err != nil {\n\treturn err\n}\nif _, err := strconv.Atoi(u.Gid); err != nil {\n\treturn fmt.Errorf(\"user %q has non-numeric gid %q in passwd/NSS source\", username, u.Gid)\n}\nuid, gid, home, err := users.LookupUnix(username)","typeGuard":"func hasValidGid(u *user.User) bool {\n\t_, err := strconv.Atoi(u.Gid)\n\treturn err == nil\n}","tryCatchPattern":"uid, gid, home, err := users.LookupUnix(username)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error parsing gid\") {\n\t\treturn fmt.Errorf(\"corrupt passwd entry for %q — fix gid column: %w\", username, err)\n\t}\n\treturn err\n}","preventionTips":["Validate gid column when generating passwd entries programmatically","Check LDAP/SSSD gidNumber attributes when using directory-based users","Recreate malformed user entries with standard tooling","Pre-validate all user IDs at service startup"],"tags":["unix","user-lookup","parsing","passwd"],"backgroundTag":"gid-parse-error","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}