lima-vm/lima · error
failed to create parent directory for path %#q: %w
Error message
failed to create parent directory for path %#q: %w
What it means
Before writing a write_files entry, the fake cloud-init code runs `os.MkdirAll` on the entry's parent directory with mode 0755. When that fails, this error wraps the OS error. It usually means a path component exists as a regular file, or the process lacks permission to create the directory.
Source
Thrown at pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go:352
return fmt.Errorf("failed to write to sudoers file %#q for user %#q: %w", sudoersPath, userName, err)
}
return f.Close()
}
func writeFiles(ctx context.Context, entry cloudinittypes.WriteFile) error {
if entry.Path == "" {
return errors.New("path is required for write_files entry")
}
perm := os.FileMode(0o644)
if entry.Permissions != "" {
p, err := strconv.ParseUint(entry.Permissions, 8, 32)
if err != nil {
return fmt.Errorf("invalid permissions %#q for path %#q: %w", entry.Permissions, entry.Path, err)
}
perm = os.FileMode(p)
}
if err := os.MkdirAll(filepath.Dir(entry.Path), 0o755); err != nil {
return fmt.Errorf("failed to create parent directory for path %#q: %w", entry.Path, err)
}
if err := os.WriteFile(entry.Path, []byte(entry.Content), perm); err != nil {
return fmt.Errorf("failed to write file for path %#q: %w", entry.Path, err)
}
if entry.Owner != "" {
cmd := exec.CommandContext(ctx, "chown", entry.Owner, entry.Path)
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)
}
}
return nil
}
func setResolvConf(ctx context.Context, resolvConf *cloudinittypes.ResolvConf) error {
// FIXME: avoid hardcoding the primary network name
const primaryNetwork = "Ethernet"
cmd := exec.CommandContext(ctx, "networksetup", append([]string{"-setdnsservers", primaryNetwork}, resolvConf.Nameservers...)...)View on GitHub (pinned to dd909d0973)
Solutions
- Verify the `path` in the write_files entry and correct any typo that points at a file used as a directory.
- Ensure the parent path exists as a directory, or that no component of it is a regular file.
- Run the guestagent with sufficient privileges, or write to a user-writable location.
- Check the wrapped os.MkdirAll error text for the exact failing component (e.g. 'not a directory', 'permission denied').
Example fix
// before path: /etc/hosts/custom.conf # /etc/hosts is a file // after path: /etc/hosts.d/custom.conf
Defensive patterns
Strategy: validation
Validate before calling
for _, e := range userData.WriteFiles {
dir := filepath.Dir(e.Path)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("path %q: parent %q is a file", e.Path, dir)
}
} Try / catch
if err := processUserData(ctx, data); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.ENOTDIR) || errors.Is(pe.Err, syscall.EACCES)) {
log.Printf("fix path/permissions: %v", err)
}
} Prevention
- Verify each write_files path's parent is a directory, not an existing file.
- Avoid writing into root-owned system paths unless running privileged.
- Keep target paths under a dedicated provisioning directory.
When it happens
Trigger: A write_files entry whose `path` has a parent directory that cannot be created: the parent exists as a file (e.g. path /etc/foo where /etc/foo is a file), the volume is read-only, or the guestagent user lacks write permission at that location.
Common situations: User-data writes to a path that collides with an existing file; writing under read-only mounts or system dirs owned by root while running unprivileged; typo in the target path creating an unintended deep hierarchy.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- failed to write file for path %#q: %w
- failed to create symlink from %#q to %#q: %w
- failed to write password file for user %#q: %w
- failed to create /etc/sudoers.d directory: %w
- failed to open sudoers file %#q: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/6ecbea7becf71c27.
Report an issue: GitHub.