lima-vm/lima · error

field `containerd.archives` must be provided

Error message

field `containerd.archives` must be provided

What it means

Lima requires `containerd.archives` to be non-empty when containerd is enabled (`containerd.system: true` and/or `containerd.user: true`). The archives list supplies the containerd tarballs to install inside the VM; without them Lima cannot provision containerd.

Source

Thrown at pkg/limayaml/validate.go:280

			if p.Script != nil && *p.Script != "" {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].script must be empty if playbook is set", i))
			}
			playbook := p.Playbook
			if _, err := os.Stat(playbook); err != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].playbook` refers to an inaccessible path: %#q: %w", i, playbook, err))
			}
			logrus.Warnf("provision mode %#q is deprecated, use `ansible-playbook %#q` instead", limatype.ProvisionModeAnsible, playbook)
		}
		if p.Script != nil {
			if strings.Contains(*p.Script, "LIMA_CIDATA") {
				logrus.Warn("provisioning scripts should not reference the LIMA_CIDATA variables")
			}
		}
	}
	needsContainerdArchives := (y.Containerd.User != nil && *y.Containerd.User) || (y.Containerd.System != nil && *y.Containerd.System)
	if needsContainerdArchives {
		if len(y.Containerd.Archives) == 0 {
			errs = errors.Join(errs, errors.New("field `containerd.archives` must be provided"))
		}
		for i, f := range y.Containerd.Archives {
			err := validateFileObject(f, fmt.Sprintf("containerd.archives[%d]", i))
			if err != nil {
				errs = errors.Join(errs, err)
			}
		}
	}
	for i, p := range y.Probes {
		if p.File != nil {
			if p.File.URL != "" {
				errs = errors.Join(errs, fmt.Errorf("field `probe[%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 `probe[%d].file.digest` support is not yet implemented", i))
			}
		}
		if p.Script != nil && !strings.HasPrefix(*p.Script, "#!") {

View on GitHub (pinned to dd909d0973)

Solutions

  1. Populate `containerd.archives` with at least one file object (location + arch + digest)
  2. Set `containerd.system` and `containerd.user` to false if containerd is not needed
  3. Let Lima apply defaults (`limactl` normally defaults archives automatically); only raw unmarshalling skips this

Example fix

// before
containerd:
  system: true
  archives: []
// after
containerd:
  system: true
  archives:
  - location: "https://github.com/containerd/containerd/releases/download/v1.7.7/containerd-1.7.7-linux-amd64.tar.gz"
    arch: x86_64
Defensive patterns

Strategy: validation

Validate before calling

if (cfg.Containerd.System != nil && *cfg.Containerd.System) || (cfg.Containerd.User != nil && *cfg.Containerd.User) {
    if len(cfg.Containerd.Archives) == 0 {
        return errors.New("containerd enabled but containerd.archives is empty")
    }
}

Type guard

func containerdNeedsArchives(c *limatype.Containerd) bool {
    return c != nil && ((c.System != nil && *c.System) || (c.User != nil && *c.User))
}

Prevention

When it happens

Trigger: Calling limactl validate/start/etc. with a config where `containerd.system` or `containerd.user` is explicitly true but `containerd.archives` is an empty list.

Common situations: Copy-pasting a config fragment enabling containerd without the archives section; after limayaml defaults were not applied (raw load without Defaulting); trimming archives during offline air-gapped setups.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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