lima-vm/lima · error

invalid boot script filename %#q: must be in format 'boot.<O

Error message

invalid boot script filename %#q: must be in format 'boot.<OS>/<SCRIPT>'

What it means

GenerateISO9660 (pkg/cidata/cidata.go:423) validates driver boot script filenames: if a filename contains '/', it must match 'boot.<OS>/<SCRIPT>' (start with 'boot.' and contain exactly one slash). Drivers returning a malformed slash-containing filename make ISO layout construction abort with this error.

Source

Thrown at pkg/cidata/cidata.go:423

		return "", err
	}

	layout, err := ExecuteTemplateCIDataISO(args)
	if err != nil {
		return "", err
	}

	driverScripts, err := drv.BootScripts(ctx)
	if err != nil {
		return "", fmt.Errorf("failed to get boot scripts: %w", err)
	}

	for filename, content := range driverScripts {
		layoutPath := path.Join("boot.Linux", filename)
		if strings.Contains(filename, "/") {
			// When the filename contains a slash, it must be in the format of "boot.<OS>/<SCRIPT>"
			if !strings.HasPrefix(filename, "boot.") || strings.Count(filename, "/") != 1 {
				return "", fmt.Errorf("invalid boot script filename %#q: must be in format 'boot.<OS>/<SCRIPT>'", filename)
			}
			layoutPath = filename
		} else {
			logrus.Warnf("Boot script filename %#q does not contain '/', treating it as a script for Linux and prefixing with 'boot.Linux/'", filename)
		}
		layout = append(layout, iso9660util.Entry{
			Path:   layoutPath,
			Reader: strings.NewReader(string(content)),
		})
	}

	layout, err = appendProvisionEntries(layout, instConfig.Provision)
	if err != nil {
		return "", err
	}

	if guestAgentBinary != "" {
		var guestAgent io.ReadCloser

View on GitHub (pinned to dd909d0973)

Solutions

  1. Inspect the driver's BootScripts() return values
  2. Rename the script to the `boot.<OS>/<SCRIPT>` form, e.g. "boot.Linux/01-setup.sh"
  3. Ensure the filename contains exactly one '/' and starts with "boot."

Example fix

// before
return map[string]string{"scripts/setup.sh": content}, nil
// after
return map[string]string{"boot.Linux/setup.sh": content}, nil
Defensive patterns

Strategy: validation

Validate before calling

func validBootScriptName(name string) bool {
    if !strings.Contains(name, "/") {
        return true // will be prefixed with boot.Linux/
    }
    return strings.HasPrefix(name, "boot.") && strings.Count(name, "/") == 1
}
// check each filename returned by drv.BootScripts(ctx) before use

Try / catch

layout, err := cidata.GenerateISO9660(ctx, instDir, args)
if err != nil && strings.Contains(err.Error(), "invalid boot script filename") {
    log.Fatalf("driver returned malformed boot script name: %v", err)
}

Prevention

When it happens

Trigger: A driver's BootScripts() returns a filename like "boot/win10.cmd" (missing dot), "boot.Linux/a/b.sh" (two slashes), or "scripts/boot.sh" (no boot. prefix) while containing '/'.

Common situations: Developing a custom driver or upgrading Lima where a driver emits a new script path that no longer matches the expected layout convention.

Related errors


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