hashicorp/nomad · error

error parsing uid: %w

Error message

error parsing uid: %w

What it means

After finding the user, LookupUnix converts the string u.Uid field to an int with strconv.Atoi; a non-numeric Uid is a corrupted or exotic user-database entry, so the conversion error is wrapped and returned.

Source

Thrown at helper/users/lookup.go:39

//
// Values are cached up to 1 hour, or 1 minute for failure cases.
func Lookup(username string) (*user.User, error) {
	return globalCache.GetUser(username)
}

// LookupUnix returns the UID, GID, and home directory for username or returns
// an error. ID values are int to work well with Go library functions.
//
// Will always fail on Windows and Plan 9.
func LookupUnix(username string) (int, int, string, error) {
	u, err := Lookup(username)
	if err != nil {
		return 0, 0, "", fmt.Errorf("error looking up user %q: %w", username, err)
	}

	uid, err := strconv.Atoi(u.Uid)
	if err != nil {
		return 0, 0, "", fmt.Errorf("error parsing uid: %w", err)
	}

	gid, err := strconv.Atoi(u.Gid)
	if err != nil {
		return 0, 0, "", fmt.Errorf("error parsing gid: %w", err)
	}

	return uid, gid, u.HomeDir, nil
}

// lock is used to serialize all user lookup at the process level, because
// some NSS implementations are not concurrency safe
var lock sync.Mutex

// internalLookupUser username while holding a global process lock.
func internalLookupUser(username string) (*user.User, error) {
	lock.Lock()
	defer lock.Unlock()

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect /etc/passwd for the target user and correct the uid field to a numeric value
  2. Check the NSS/LDAP/SSSD source for malformed uidNumber attributes
  3. Recreate the user entry with standard tooling (useradd) instead of manual edits

Example fix

// before
nomad:x:100 :100::/home/nomad:   # malformed uid
// after
nomad:x:1000:1000::/home/nomad:  # valid numeric uid
Defensive patterns

Strategy: validation

Validate before calling

u, err := user.Lookup(username)
if err != nil {
	return err
}
if _, err := strconv.Atoi(u.Uid); err != nil {
	return fmt.Errorf("user %q has non-numeric uid %q in passwd/NSS source", username, u.Uid)
}
uid, gid, home, err := users.LookupUnix(username)

Type guard

func hasNumericIDs(u *user.User) bool {
	_, uidErr := strconv.Atoi(u.Uid)
	_, gidErr := strconv.Atoi(u.Gid)
	return uidErr == nil && gidErr == nil
}

Try / catch

uid, gid, home, err := users.LookupUnix(username)
if err != nil {
	if strings.Contains(err.Error(), "error parsing uid") {
		return fmt.Errorf("corrupt passwd entry for %q — fix uid column: %w", username, err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling users.LookupUnix for a user whose /etc/passwd (or NSS source) entry has a Uid field that is not a plain integer — malformed passwd line, LDAP/NSS plugin returning bad data.

Common situations: Hand-edited /etc/passwd with a typo in the uid column; NSS backends (LDAP, SSSD) returning malformed attributes; automated tooling writing invalid passwd entries.

Related errors


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