abiosoft/colima · error

error preparing storage pools directory

Error message

error preparing storage pools directory: %w

What it means

wipeDisk begins by running 'sudo rm -rf <disk_file> <meta_dir>' in the guest to clear old pool artifacts before recreating storage; that cleanup command failed. rm failures here usually mean the pool file is busy (zfs still holding it), sudo failed, or the guest filesystem errored.

Solutions

  1. Check what holds the files: 'colima ssh -- sudo lsof +D /var/lib/incus; sudo zpool list'
  2. Export any imported pool first: 'colima ssh -- sudo zpool export <pool>' then retry
  3. Retry after a full stop/start: 'colima stop && colima start'
  4. If the data volume is faulty, recreate the VM: 'colima delete && colima start'
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure nothing holds the pool before wiping
if c.poolImported() {
    _ = c.guest.RunQuiet("sh", "-c", "sudo zpool export "+poolName)
}

Try / catch

if err := c.guest.RunQuiet("sh", "-c", deleteScript); err != nil {
    // busy files clear after services stop; retry once post-stop
    _ = c.systemctl.Stop("incus.service")
    if err2 := c.guest.RunQuiet("sh", "-c", deleteScript); err2 != nil {
        return fmt.Errorf("error preparing storage pools directory: %w", err2)
    }
}

Prevention

When it happens

Trigger: guest.RunQuiet('sh','-c', 'sudo rm -rf ...') errors: zfs pool still imported and holding the .img, another process has files open under the meta dir, permissions changed, guest disk in read-only/error state.

Common situations: Wiping after a failed recovery where the pool got imported in between, concurrent incus operations in the guest, disk I/O errors on the data volume.

Related errors


AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15). Data as JSON: /api/errors/7ca12a81e9e69d70. Report an issue: GitHub.

Appendix: source

Thrown at environment/container/incus/incus.go:486

		return err
	}

	if out != poolName {
		return fmt.Errorf("default storage pool recovery failure")
	}

	return nil
}

func (c *incusRuntime) wipeDisk(size int) error {
	// prepare by deleting relevant files/directories
	deleteScript := strings.NewReplacer(
		"{disk_file}", poolDiskFile,
		"{meta_dir}", poolMetaDir,
	).Replace("sudo rm -rf {disk_file} {meta_dir}")

	if err := c.guest.RunQuiet("sh", "-c", deleteScript); err != nil {
		return fmt.Errorf("error preparing storage pools directory: %w", err)
	}

	// create new storage pool
	var diskSize = fmt.Sprintf("%dGiB", size)
	return c.guest.RunQuiet("sudo", "incus", "storage", "create", poolName, storageDriver, "size="+diskSize)
}

// migrationScript returns a script that migrates from the old disk layout
// (separate incus-disks and incus-backups subdirectories) to the new layout
// (full /var/lib/incus directory).
func migrationScript() string {
	mountPoint := limautil.MountPoint()
	return `MOUNT_POINT="` + mountPoint + `"
if [ -d "$MOUNT_POINT/incus-disks" ] && [ ! -d "$MOUNT_POINT/incus" ]; then
  mkdir -p "$MOUNT_POINT/incus"
  if [ -d /var/lib/incus ]; then
    cp -a /var/lib/incus/. "$MOUNT_POINT/incus/"
  fi

View on GitHub (pinned to c3a5f9184d)