lima-vm/lima · error

binary %#q seems signed but lacking the `com.apple.security.

Error message

binary %#q seems signed but lacking the `com.apple.security.hypervisor` entitlement

What it means

When codesign output shows the QEMU binary is signed but the entitlements do not include `com.apple.security.hypervisor`, IsSigned returns this explicit error. It distinguishes a signature-valid-but-unentitled binary from outright codesign failures (errors 346/347).

Source

Thrown at pkg/driver/qemu/entitlementutil/entitlementutil.go:37

// IsSigned returns an error if the binary is not signed, or the sign is invalid,
// or not associated with the "com.apple.security.hypervisor" entitlement.
func IsSigned(ctx context.Context, qExe string) error {
	cmd := exec.CommandContext(ctx, "codesign", "--verify", qExe)
	out, err := cmd.CombinedOutput()
	logrus.WithError(err).Debugf("Executed %v: out=%#q", cmd.Args, string(out))
	if err != nil {
		return fmt.Errorf("failed to run %v: %w (out=%#q)", cmd.Args, err, string(out))
	}

	cmd = exec.CommandContext(ctx, "codesign", "--display", "--entitlements", "-", "--xml", qExe)
	out, err = cmd.CombinedOutput()
	logrus.WithError(err).Debugf("Executed %v: out=%#q", cmd.Args, string(out))
	if err != nil {
		return fmt.Errorf("failed to run %v: %w (out=%#q)", cmd.Args, err, string(out))
	}
	if !strings.Contains(string(out), "com.apple.security.hypervisor") {
		return fmt.Errorf("binary %#q seems signed but lacking the `com.apple.security.hypervisor` entitlement", qExe)
	}
	return nil
}

func Sign(ctx context.Context, qExe string) error {
	ent, err := os.CreateTemp("", "lima-qemu-entitlements-*.xml")
	if err != nil {
		return fmt.Errorf("failed to create a temporary file for signing QEMU binary: %w", err)
	}
	entName := ent.Name()
	defer os.RemoveAll(entName)
	const entXML = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.hypervisor</key>
    <true/>
  </dict>

View on GitHub (pinned to dd909d0973)

Solutions

  1. Re-sign the binary via Lima's prompt (Sign applies the hypervisor entitlement automatically)
  2. Manually sign with an entitlements plist containing com.apple.security.hypervisor=true
  3. Replace the binary with one built/signed for Apple Virtualization use

Example fix

// before
codesign --force --sign - qemu-system-aarch64   # no entitlements
// after
codesign --entitlements hyp.xml --force --sign - qemu-system-aarch64  # hyp.xml grants com.apple.security.hypervisor
Defensive patterns

Strategy: validation

Validate before calling

ent, _ := exec.Command("codesign", "--display", "--entitlements", "-", "--xml", qemuExe).CombinedOutput()
if !strings.Contains(string(ent), "com.apple.security.hypervisor") {
    return errors.New("qemu lacks hypervisor entitlement; re-sign required")
}

Prevention

When it happens

Trigger: IsSigned succeeds at --verify but `strings.Contains(codesign --display output, "com.apple.security.hypervisor")` is false for the given qemu executable path.

Common situations: qemu binaries from third-party package managers signed with minimal entitlements; manually re-signed binaries where the entitlements plist omitted the hypervisor key.

Related errors


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