lima-vm/lima · error
provision mode %#q is not supported on Windows VM
Error message
provision mode %#q is not supported on Windows VM
What it means
During `limayaml.Validate`, Lima rejects provisioning scripts whose mode is unsupported on a Windows guest VM. Modes `ansible`, `boot`, and `yq` rely on guest capabilities (ansible provisioning, boot-time hooks, yq expression evaluation) that are not implemented for `os: windows` templates, so validation errors out before the VM is created.
Source
Thrown at pkg/limayaml/validate.go:212
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].file.url` must be empty during validation (script should already be embedded)", i))
}
if p.File.Digest != nil {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].file.digest` support is not yet implemented", i))
}
}
switch p.Mode {
case limatype.ProvisionModeSystem, limatype.ProvisionModeUser, limatype.ProvisionModeBoot, limatype.ProvisionModeData, limatype.ProvisionModeDependency, limatype.ProvisionModeAnsible, limatype.ProvisionModeYQ:
default:
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].mode` must one of %#q, %#q, %#q, %#q, %#q, %#q, or %#q",
i, limatype.ProvisionModeSystem, limatype.ProvisionModeUser, limatype.ProvisionModeBoot, limatype.ProvisionModeData, limatype.ProvisionModeDependency, limatype.ProvisionModeAnsible, limatype.ProvisionModeYQ))
}
if p.Mode != limatype.ProvisionModeDependency && p.SkipDefaultDependencyResolution != nil {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].mode` cannot set skipDefaultDependencyResolution, only valid on scripts of type %#q",
i, limatype.ProvisionModeDependency))
}
if *y.OS == limatype.WINDOWS && (p.Mode == limatype.ProvisionModeAnsible || p.Mode == limatype.ProvisionModeBoot || p.Mode == limatype.ProvisionModeYQ) {
errs = errors.Join(errs, fmt.Errorf("provision mode %#q is not supported on Windows VM", p.Mode))
}
// This can lead to fatal Panic if p.Path is nil, better to return an error here
switch p.Mode {
case limatype.ProvisionModeData, limatype.ProvisionModeYQ:
if p.Path == nil {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].path` must not be empty when mode is %#q", i, p.Mode))
return errs
}
if !path.IsAbs(*p.Path) {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].path` must be an absolute path", i))
}
if p.Mode == limatype.ProvisionModeData && p.Content == nil {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].content` must not be empty when mode is %#q", i, p.Mode))
}
if p.Mode == limatype.ProvisionModeYQ && p.Expression == nil {
errs = errors.Join(errs, fmt.Errorf("field `provision[%d].expression` must not be empty when mode is %#q", i, p.Mode))
}View on GitHub (pinned to dd909d0973)
Solutions
- Change os to "linux" if the workload does not actually require Windows.
- Remove or convert the ansible/boot/yq provision entries to supported modes (e.g. mode: user or system scripts) for the Windows template.
- Split the config: keep Windows-specific provisioning in mode: user/system scripts and move yq/ansible logic to the host side.
Example fix
# before
os: windows
provision:
- mode: boot
script: echo booting
# after
os: windows
provision:
- mode: user
script: echo starting Defensive patterns
Strategy: validation
Validate before calling
if cfg.OS != nil && *cfg.OS == "windows" {
for i, p := range cfg.Provision {
switch p.Mode {
case "ansible", "boot", "yq":
return fmt.Errorf("provision[%d]: mode %q unsupported on windows", i, p.Mode)
}
}
} Type guard
func provisionModeWindowsSafe(mode limatype.ProvisionMode) bool {
return mode != limatype.ProvisionModeAnsible && mode != limatype.ProvisionModeBoot && mode != limatype.ProvisionModeYQ
} Try / catch
if err := limayaml.Validate(y, false, "template.yaml"); err != nil {
if strings.Contains(err.Error(), "not supported on Windows VM") {
return fmt.Errorf("template targets windows; migrate offending provision entries: %w", err)
}
return err
} Prevention
- Keep a separate windows variant of shared templates with only user/system/data provision modes.
- Run limactl template validate with the target os before distribution.
- Document that ansible, boot, and yq provision modes are Linux-guest only.
When it happens
Trigger: Running limactl create/start/template validate (or edit/restart/apply/clone/rename, all of which call Validate) on a template where `os: windows` and at least one provision entry has mode "ansible", "boot", or "yq".
Common situations: Porting a Linux template to Windows by only changing os: windows while keeping the original provision modes; a shared base template with boot-mode scripts reused for a Windows instance; adding a yq-mode file edit step to a Windows template without realizing the restriction.
Related errors
- field `provision[%d].mode` cannot set skipDefaultDependencyR
- field `provision[%d].path` must not be empty when mode is %#
- field `provision[%d].path` must be an absolute path
- field `provision[%d].content` must not be empty when mode is
- field `provision[%d].expression` must not be empty when mode
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/0e0cd4cd96827210.
Report an issue: GitHub.