lima-vm/lima · error

failed to create a temporary file for signing QEMU binary: %

Error message

failed to create a temporary file for signing QEMU binary: %w

What it means

Sign re-signs the QEMU binary with the hypervisor entitlement by writing the entitlements plist to a temporary file. If os.CreateTemp fails, Sign returns `failed to create a temporary file for signing QEMU binary` wrapping the OS error, before any codesign invocation happens.

Source

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

		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>
</plist>`
	if _, err = ent.WriteString(entXML); err != nil {
		ent.Close()
		return fmt.Errorf("failed to write to a temporary file %#q for signing QEMU binary: %w", entName, err)
	}
	ent.Close()
	signCmd := exec.CommandContext(ctx, "codesign", "--sign", "-", "--entitlements", entName, "--force", qExe)
	out, err := signCmd.CombinedOutput()

View on GitHub (pinned to dd909d0973)

Solutions

  1. Check and fix TMPDIR: `echo $TMPDIR`; ensure it exists and is writable
  2. Free disk space if the volume is full
  3. Re-run the command; the temp file is cleaned up automatically (defer os.RemoveAll)

Example fix

// before
export TMPDIR=/nonexistent
// after
unset TMPDIR   # or export TMPDIR=$(mktemp -d)
Defensive patterns

Strategy: try-catch

Validate before calling

if f, err := os.CreateTemp("", "probe-*"); err != nil {
    return errors.New("TMPDIR not writable; fix before signing qemu")
} else { f.Close(); os.Remove(f.Name()) }

Try / catch

err := entitlementutil.Sign(ctx, qemuExe)
if err != nil && strings.Contains(err.Error(), "temporary file") {
    // check TMPDIR writability/disk space, then retry
}

Prevention

When it happens

Trigger: os.CreateTemp("", "lima-qemu-entitlements-*.xml") failing — typically TMPDIR pointing to a non-writable, full, or nonexistent directory, or resource exhaustion.

Common situations: TMPDIR set to a read-only path in CI or sandboxed shells; full disk; hardened environment restricting temp file creation.

Related errors


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