lima-vm/lima · error
failed to unmount %#q: %w (output=%#q)
Error message
failed to unmount %#q: %w (output=%#q)
What it means
Umount() on macOS runs the external `umount <mnt>` command and, on non-zero exit, returns this error wrapping the exit error plus the command's combined output. It signals that the kernel/refused unmount of the given path.
Source
Thrown at pkg/osutil/mount_darwin.go:35
func Mount(ctx context.Context, fs, dev, mnt string, options []string) error {
args := []string{"-t", fs}
if len(options) > 0 {
args = append(args, "-o", strings.Join(options, ","))
}
args = append(args, dev, mnt)
cmd := exec.CommandContext(ctx, "mount", args...)
logrus.Debugf("Executing command: %v", cmd.Args)
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to mount %#q on %#q: %w (output=%#q)", dev, mnt, err, output)
}
return nil
}
func Umount(ctx context.Context, mnt string) error {
cmd := exec.CommandContext(ctx, "umount", mnt)
logrus.Debugf("Executing command: %v", cmd.Args)
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to unmount %#q: %w (output=%#q)", mnt, err, output)
}
return nil
}
View on GitHub (pinned to dd909d0973)
Solutions
- Read the `output=` field — umount reports 'busy' vs 'not currently mounted' distinctly.
- For busy mounts, find and stop processes using it (lsof +f -- <mnt> or diskutil unmount force).
- Ignore 'not mounted' errors as idempotent cleanup if appropriate.
- Retry after the consumer (VM) has fully exited.
Example fix
// before: umount while guestagent still running -> busy
// after: stop VM first, then umount with retry
if err := osutil.Umount(ctx, mnt); err != nil && !strings.Contains(err.Error(), "not currently mounted") { return err } Defensive patterns
Strategy: retry
Validate before calling
// only attempt umount if it is actually a mount point
out, _ := exec.Command("mount").Output()
if !bytes.Contains(out, []byte(mnt)) {
return nil // already unmounted; skip
} Try / catch
err := osutil.Umount(ctx, mnt)
if err != nil && strings.Contains(err.Error(), "busy") {
time.Sleep(500 * time.Millisecond)
err = osutil.Umount(ctx, mnt) // retry after consumers exit
} Prevention
- Fully stop the VM/consumer before unmounting
- Treat 'not currently mounted' as success for idempotent cleanup
- Use lsof to verify no process holds the mount before teardown
When it happens
Trigger: Umount is called on a path that is still busy (open files, running processes), not a mount point, or requires privileges and lacks them; the umount subprocess exits non-zero.
Common situations: Tearing down a Lima instance while a VM process still holds the mount; unmounting an already-unmounted path; resource busy during shutdown sequencing.
Related errors
- failed to mount %#q on %#q: %w (output=%#q)
- failed to create temp file: %w
- failed to write temp plist: %w
- failed to create a temporary file for signing QEMU binary: %
- failed to write file for path %#q: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/cf1879423b31eb12.
Report an issue: GitHub.