{"record":{"id":"ce3fd2af8138a75e","repo":"lima-vm/lima","slug":"failed-to-create-etc-sudoers-d-directory-w","errorCode":null,"errorMessage":"failed to create /etc/sudoers.d directory: %w","messagePattern":"failed to create /etc/sudoers\\.d directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go","lineNumber":325,"sourceCode":"\t\t\treturn fmt.Errorf(\"failed to chown %#q for user %#q: %w\", f, u.Name, err)\n\t\t}\n\t}\n\tif u.Sudo != \"\" {\n\t\tif err := writeSudoers(u.Name, u.Sudo); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write sudoers file for user %#q: %w\", u.Name, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// writeSudoers appends a sudoers entry for the given user.\n// writeSudoers is expected be called only once on creating the user account.\nfunc writeSudoers(userName, sudo string) error {\n\tif strings.Contains(sudo, \"\\n\") {\n\t\treturn errors.New(\"sudo field must not contain newline characters\")\n\t}\n\tif err := os.MkdirAll(\"/etc/sudoers.d\", 0o700); err != nil {\n\t\treturn fmt.Errorf(\"failed to create /etc/sudoers.d directory: %w\", err)\n\t}\n\tsudoersPath := \"/etc/sudoers.d/90-cloud-init-users\"\n\tf, err := os.OpenFile(sudoersPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o400)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open sudoers file %#q: %w\", sudoersPath, err)\n\t}\n\tif _, err = fmt.Fprintf(f, \"%s %s\\n\", userName, sudo); err != nil {\n\t\t_ = f.Close()\n\t\treturn fmt.Errorf(\"failed to write to sudoers file %#q for user %#q: %w\", sudoersPath, userName, err)\n\t}\n\treturn f.Close()\n}\n\nfunc writeFiles(ctx context.Context, entry cloudinittypes.WriteFile) error {\n\tif entry.Path == \"\" {\n\t\treturn errors.New(\"path is required for write_files entry\")\n\t}\n\tperm := os.FileMode(0o644)","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go#L307-L343","documentation":"os.MkdirAll(\"/etc/sudoers.d\", 0o700) failed while preparing to append the user's sudoers entry. On a healthy macOS guest this directory normally exists; failure indicates the root filesystem is not writable by the agent or an unusual system state. The user's sudo setup is aborted.","triggerScenarios":"writeSudoers runs (user has a `sudo` field) and creating /etc/sudoers.d fails: read-only root volume, EPERM because the guestagent is not root, or /etc/sudoers.d exists as a regular file.","commonSituations":"Running the guestagent unprivileged in custom setups; sealed/system read-only volume configurations; a previous provisioning step replaced /etc/sudoers.d with a file; full disk (ENOSPC).","solutions":["Ensure the Lima guestagent runs as root inside the VM","Check the root volume is writable (`touch /etc/test`)","Verify /etc/sudoers.d is a directory, not a regular file; fix or recreate the instance","Free disk space if the wrapped error is ENOSPC"],"exampleFix":"// inside the VM (recovery)\nsudo rm -f /etc/sudoers.d        # only if it is a regular file\nsudo mkdir -p /etc/sudoers.d && sudo chmod 700 /etc/sudoers.d","handlingStrategy":"validation","validationCode":"if fi, err := os.Lstat(\"/etc/sudoers.d\"); err == nil && !fi.IsDir() {\n    return errors.New(\"/etc/sudoers.d exists but is not a directory\")\n}\nif err := os.MkdirAll(\"/etc/sudoers.d\", 0o700); err != nil {\n    return fmt.Errorf(\"/etc/sudoers.d not preparable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := processUserData(ctx, data); err != nil {\n    var pe *os.PathError\n    if errors.As(err, &pe) && strings.Contains(err.Error(), \"sudoers.d directory\") {\n        log.Printf(\"cannot prepare %s: %v — check root privileges and writable /etc\", pe.Path, pe.Err)\n    }\n}","preventionTips":["Ensure the guestagent runs as root","Keep the root volume writable and non-full","Confirm /etc/sudoers.d is a directory before reprovisioning"],"tags":["sudoers","filesystem","permissions","macos"],"backgroundTag":"mkdir-failed","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}