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.MutexView on GitHub (pinned to 482b49bf1a)
Solutions
- Create the user on the host (useradd) or fix the username in configuration
- Ensure /etc/passwd and /etc/nsswitch.conf are correct in the runtime environment
- 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
- Provision required OS users in install/startup scripts before the service runs
- Check /etc/passwd and nsswitch.conf in container images
- Gate LookupUnix behind a runtime.GOOS check; it always fails on Windows/Plan 9
- Validate configured usernames at config load, not deep in file-chown logic
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
- failed to get current user: %w
- failed to identify user %v: %v
- unable to convert userid %s to integer
- unable to lookup user's group membership: %w
- error parsing uid: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/7283e251caa7e821.
Report an issue: GitHub.