lima-vm/lima · error
failed to create .ssh directory for user %#q: %w
Error message
failed to create .ssh directory for user %#q: %w
What it means
The agent could not create the `<homedir>/.ssh` directory (mode 0700) for the freshly created user. This directory is required to install `authorized_keys`. The error wraps the raw os.MkdirAll failure and aborts provisioning of this user.
Source
Thrown at pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go:298
if err = populateHomeDir(ctx, uid, homedir); err != nil {
return fmt.Errorf("failed to populate home directory for user %#q: %w", u.Name, err)
}
cmd = exec.CommandContext(ctx, "chmod", "700", homedir)
logrus.Infof("Executing command: %v", cmd.Args)
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to execute command %v: %w (output=%#q)", cmd.Args, err, output)
}
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
}View on GitHub (pinned to dd909d0973)
Solutions
- Check for a conflicting file at `<homedir>/.ssh` and remove it
- Verify disk space and writability of the home directory as root
- Read the wrapped errno in the error message to pinpoint the cause
- Delete and recreate the instance if prior partial provisioning left bad state
Example fix
// inside the VM, before reprovisioning sudo rm -f /Users/alice/.ssh # if it exists as a regular file
Defensive patterns
Strategy: validation
Validate before calling
sshDir := filepath.Join(home, ".ssh")
if st, err := os.Lstat(sshDir); err == nil && !st.IsDir() {
return fmt.Errorf("%s exists and is not a directory; remove it first", sshDir)
} Try / catch
if err := processUserData(ctx, data); err != nil {
var pe *os.PathError
if errors.As(err, &pe) && strings.Contains(err.Error(), ".ssh directory") {
log.Printf("mkdir %s failed: %v", pe.Path, pe.Err)
}
} Prevention
- Delete stale `.ssh` files from earlier failed provisions
- Verify writability of the home directory as root before provisioning
- Watch guest disk usage (df -h) before reprovisioning
When it happens
Trigger: os.MkdirAll(homedir/.ssh, 0o700) fails in createUser during processUserData on a darwin guest. Causes: home path is a file instead of a directory, parent not writable, ENOSPC, or read-only filesystem.
Common situations: A stale file named `.ssh` exists at the home path from a previous provisioning attempt; the custom `home` from user-data points into a read-only or restricted location; disk image full.
Related errors
- failed to write authorized_keys file for user %#q: %w
- failed to write password file for user %#q: %w
- failed to write to sudoers file %#q for user %#q: %w
- failed to create temp file: %w
- failed to write temp plist: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/2826ee00d9552db3.
Report an issue: GitHub.