lima-vm/lima · error
failed to write authorized_keys file for user %#q: %w
Error message
failed to write authorized_keys file for user %#q: %w
What it means
Writing the `authorized_keys` file (`<homedir>/.ssh/authorized_keys`, mode 0600) failed after the `.ssh` directory was created successfully. Without this file SSH public-key login for the user cannot work, so provisioning aborts. The wrapped os.WriteFile error carries the actual cause.
Source
Thrown at pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go:303
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
}
// 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") {View on GitHub (pinned to dd909d0973)
Solutions
- Check guest disk space and free space if needed
- Verify `<homedir>/.ssh` exists as a writable directory (mode 0700)
- Inspect the wrapped errno (EACCES/ENOSPC/EIO) in the log
- Re-run provisioning after fixing; keys come from the user-data `users[].ssh_authorized_keys` field
Example fix
// before: instance disk full limactl disk resize / grow instance disk // after: reprovision limactl start instance.yaml
Defensive patterns
Strategy: validation
Validate before calling
dotSSH := filepath.Join(home, ".ssh")
st, err := os.Stat(dotSSH)
if err != nil || !st.IsDir() || st.Mode().Perm()&0o200 == 0 {
return fmt.Errorf("%s must exist as a writable directory", dotSSH)
} Try / catch
if err := processUserData(ctx, data); err != nil {
var pe *os.PathError
if errors.As(err, &pe) && strings.Contains(err.Error(), "authorized_keys") {
log.Printf("authorized_keys write failed at %s: %v", pe.Path, pe.Err)
}
} Prevention
- Provision with sufficient free disk space
- Keep ssh_authorized_keys entries well-formed (one key per list item)
- Avoid security tooling that blocks writes into ~/.ssh during provisioning
When it happens
Trigger: os.WriteFile(authKeysPath, joined SSH keys, 0o600) fails in createUser during processUserData. Causes: ENOSPC, EACCES on the just-created directory, I/O errors, or security software blocking writes into .ssh.
Common situations: Disk-full VM during heavy provisioning; EDR/antivirus on macOS guest restricting .ssh writes; extremely long ssh key lists hitting quota/limits.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to create .ssh directory 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/3074072e0338be8f.
Report an issue: GitHub.