lima-vm/lima · error
failed to chown %#q for user %#q: %w
Error message
failed to chown %#q for user %#q: %w
What it means
os.Chown failed while assigning the user's UID to the password file, the `.ssh` directory, or `authorized_keys` (group is left unchanged via gid -1). The agent needs these files owned by the new user so SSH login and password retrieval work. The error names the exact file path (`%#q`) that failed.
Source
Thrown at pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go:307
pwPath := filepath.Join(homedir, "password")
if err = os.WriteFile(pwPath, []byte(pw+"\n"), 0o400); err != nil {
return fmt.Errorf("failed to write password file for user %#q: %w", u.Name, err)
}
logrus.Infof("Created user %#q. The password is stored in %#q", u.Name, pwPath)
dotSSHPath := filepath.Join(homedir, ".ssh")
if err = os.MkdirAll(dotSSHPath, 0o700); err != nil {
return fmt.Errorf("failed to create .ssh directory for user %#q: %w", u.Name, err)
}
authKeysPath := filepath.Join(dotSSHPath, "authorized_keys")
authKeysContent := strings.Join(u.SSHAuthorizedKeys, "\n")
if err = os.WriteFile(authKeysPath, []byte(authKeysContent), 0o600); err != nil {
return fmt.Errorf("failed to write authorized_keys file for user %#q: %w", u.Name, err)
}
for _, f := range []string{pwPath, dotSSHPath, authKeysPath} {
if err = os.Chown(f, uid, -1); err != nil {
return fmt.Errorf("failed to chown %#q for user %#q: %w", f, u.Name, err)
}
}
if u.Sudo != "" {
if err := writeSudoers(u.Name, u.Sudo); err != nil {
return fmt.Errorf("failed to write sudoers file for user %#q: %w", u.Name, err)
}
}
return nil
}
// writeSudoers appends a sudoers entry for the given user.
// writeSudoers is expected be called only once on creating the user account.
func writeSudoers(userName, sudo string) error {
if strings.Contains(sudo, "\n") {
return errors.New("sudo field must not contain newline characters")
}
if err := os.MkdirAll("/etc/sudoers.d", 0o700); err != nil {
return fmt.Errorf("failed to create /etc/sudoers.d directory: %w", err)View on GitHub (pinned to dd909d0973)
Solutions
- Confirm the guestagent runs as root (chown requires privileges)
- Check the log line 'Requested UID ... but the system assigned UID ...' for UID conflicts and pick a free UID in user-data
- Verify the UID in the users entry is numeric and not already in use (`dscl . -list /users UniqueID`)
- Inspect the wrapped errno (EPERM/EINVAL) for the failing path shown in the message
Example fix
// before users: - name: alice uid: "501" # already used by the default macOS user // after users: - name: alice uid: "502"
Defensive patterns
Strategy: validation
Validate before calling
// verify the requested UID is free on the macOS guest
out, err := exec.Command("dscl", ".", "-list", "/users", "UniqueID").Output()
if err == nil && strings.Contains(string(out), "\t"+uid+"\n") {
return fmt.Errorf("uid %s already in use; pick another", uid)
}
if os.Geteuid() != 0 {
return errors.New("chown requires root; run guestagent as root")
} Try / catch
if err := processUserData(ctx, data); err != nil {
var se *os.LinkError
if errors.As(err, &se) && strings.Contains(err.Error(), "chown") {
log.Printf("chown failed (perm=%d): %v — check UID conflicts and root privileges", se.Perm, se.Err)
}
} Prevention
- Run the guestagent as root
- Choose UIDs that do not collide with existing macOS users (check dscl output)
- Rely on the agent's UID-lookup fallback logs to detect reassignments early
When it happens
Trigger: os.Chown(f, uid, -1) returns an error in createUser for one of pwPath, dotSSHPath, or authKeysPath, during processUserData on darwin. Common causes: the requested UID does not exist/reserve on the system (e.g. macOS Setup Assistant assigned a different UID and the Lookup fallback was skipped or failed), or the process lacks root privileges.
Common situations: User-data requests a UID already taken or reserved on macOS; agent runs without root; chown restrictions from sandbox/MDM profiles; UID collision when a prior user with the same UID exists.
Related errors
- failed to install plist to %s: %w
- failed to remove %s: %w
- unable to connect to guest agent via vsock port 2222
- failed to enable SSHD: %w
- failed to write password file for user %#q: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/d1866cddfe454271.
Report an issue: GitHub.