lima-vm/lima · error

invalid plist: IORegistryEntryChildren not found or empty

Error message

invalid plist: IORegistryEntryChildren not found or empty

What it means

After confirming the plist root is a dict, the macOS machine-ID parser looks for the IORegistryEntryChildren key and requires a non-empty array under it. This error is returned when that key is absent, not an array, or empty — i.e. the ioreg dump lacks the expected child registry entries.

Source

Thrown at pkg/osutil/machineid.go:72

		if err == nil {
			return strings.TrimSpace(string(b)), nil
		}
	}
	return "", fmt.Errorf("no machine-id found, tried %v", candidates)
}

func parseIOPlatformUUIDFromIOPlatformExpertDevice(r io.Reader) (string, error) {
	var p plist.Plist
	dec := xml.NewDecoder(r)
	if err := dec.Decode(&p); err != nil {
		return "", err
	}
	if p.Value.Dict == nil {
		return "", errors.New("invalid plist: top-level value is not a dict")
	}
	ioRegistryEntryChildren, ok := p.Value.Dict["IORegistryEntryChildren"]
	if !ok || ioRegistryEntryChildren.Array == nil || len(ioRegistryEntryChildren.Array) == 0 {
		return "", errors.New("invalid plist: IORegistryEntryChildren not found or empty")
	}
	for _, child := range ioRegistryEntryChildren.Array {
		if child.Dict == nil {
			continue
		}
		ioPlatformUUID, ok := child.Dict["IOPlatformUUID"]
		if !ok || ioPlatformUUID.String == nil {
			continue
		}
		return *ioPlatformUUID.String, nil
	}

	return "", errors.New("invalid plist: IOPlatformUUID not found in any child of IORegistryEntryChildren")
}

View on GitHub (pinned to dd909d0973)

Solutions

  1. Run `ioreg -rd1 -c IOPlatformExpertDevice` manually and confirm IORegistryEntryChildren appears with entries.
  2. Update macOS/lima if the ioreg output format changed.
  3. Check that the full ioreg output (not truncated by a pipe) is being parsed.
  4. Fall back to hostname identity; make sure the hostname is stable and unique.

Example fix

// before (wrong flags, no children)
ioreg -c IOPlatformExpertDevice | head -1
// after (full dump lima expects)
ioreg -rd1 -c IOPlatformExpertDevice
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("ioreg", "-rd1", "-c", "IOPlatformExpertDevice").Output()
if !bytes.Contains(out, []byte("IORegistryEntryChildren")) {
    // environment will not yield IORegistryEntryChildren; skip machine-id and use hostname
}

Type guard

func hasIORegistryEntryChildren(r io.Reader) bool {
    var p plist.Plist
    if err := xml.NewDecoder(r).Decode(&p); err != nil || p.Value.Dict == nil {
        return false
    }
    ch, ok := p.Value.Dict["IORegistryEntryChildren"]
    return ok && ch.Array != nil && len(ch.Array) > 0
}

Try / catch

id, err := osutil.MachineID(ctx)
if err != nil && strings.Contains(err.Error(), "IORegistryEntryChildren") {
    log.Warn("ioreg has no children; using hostname as machine id")
}

Prevention

When it happens

Trigger: machineID() on macOS parses an ioreg plist whose dict has no IORegistryEntryChildren key, or whose value is nil/empty array; also triggered by unit tests feeding malformed plists.

Common situations: Running ioreg with wrong flags (missing -c IOPlatformExpertDevice or wrong depth) producing an empty tree; VMs or Hackintosh-ish environments where IOPlatformExpertDevice exposes no children; truncated ioreg output.

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/2a1362a48983e4cf. Report an issue: GitHub.