hashicorp/nomad · error

error looking up user %q: %w

Error message

error looking up user %q: %w

What it means

LookupUnix resolves a username to uid/gid/home via user.Lookup and wraps any lookup failure with the username and the underlying error. It always fails on Windows and Plan 9, and otherwise indicates the OS user database has no such user or the lookup mechanism failed.

Source

Thrown at helper/users/lookup.go:34

)

var globalCache = newCache()

// Lookup returns the user.User entry associated with the given username.
//
// 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

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Create the user on the host (useradd) or fix the username in configuration
  2. Ensure /etc/passwd and /etc/nsswitch.conf are correct in the runtime environment
  3. On Windows/Plan 9, use a platform-independent lookup path — LookupUnix is documented to always fail there

Example fix

// before
uid, gid, home, err := users.LookupUnix("nomad-agent")
// after
if _, lookupErr := user.Lookup("nomad-agent"); lookupErr != nil {
	log.Fatalf("required OS user missing: %v", lookupErr)
}
uid, gid, home, err := users.LookupUnix("nomad-agent")
Defensive patterns

Strategy: validation

Validate before calling

if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
	return errors.New("LookupUnix unsupported on this platform")
}
if _, err := user.Lookup(username); err != nil {
	return fmt.Errorf("OS user %q must exist before start: %w", username, err)
}
uid, gid, home, err := users.LookupUnix(username)

Type guard

func userExists(username string) bool {
	_, err := user.Lookup(username)
	return err == nil
}

Try / catch

uid, gid, home, err := users.LookupUnix(username)
if err != nil {
	var uerr *user.UnknownUserError
	if errors.As(err, &uerr) || strings.Contains(err.Error(), "error looking up user") {
		return fmt.Errorf("create OS user %q or fix config: %w", username, err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling users.LookupUnix(username) (directly or via LookupUser, chownDestination, writeFileFor, setSocketOwner) with a username that user.Lookup cannot resolve — unknown user, NSS misconfiguration, or an unsupported platform.

Common situations: Config references a service user that was never created on the host; running in a minimal/chroot container image without /etc/passwd entries; stale config after the user was removed.

Related errors


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