lima-vm/lima · error

failed to download %#q: %w

Error message

failed to download %#q: %w

What it means

DownloadFile wraps any error returned by downloader.Download into "failed to download %#q: %w". This means the actual download (network fetch into cache) failed for the given location, with the underlying cause (HTTP error, DNS failure, digest mismatch, context cancellation) preserved.

Source

Thrown at pkg/fileutils/download.go:40

func DownloadFile(ctx context.Context, dest string, f limatype.File, decompress bool, description string, expectedArch limatype.Arch, supportedImageFormats []string) (string, error) {
	if f.Arch != expectedArch {
		return "", fmt.Errorf("%w: %#q: unsupported arch: %#q", ErrSkipped, f.Location, f.Arch)
	}
	fields := logrus.Fields{"location": f.Location, "arch": f.Arch, "digest": f.Digest}
	logrus.WithFields(fields).Infof("Attempting to download %s", description)
	opts := []downloader.Opt{
		downloader.WithCache(),
		downloader.WithDecompress(decompress),
		downloader.WithDescription(fmt.Sprintf("%s (%s)", description, path.Base(f.Location))),
		downloader.WithExpectedDigest(f.Digest),
	}
	if len(supportedImageFormats) > 0 {
		opts = append(opts, downloader.WithImageFormats(supportedImageFormats))
	}

	res, err := downloader.Download(ctx, dest, f.Location, opts...)
	if err != nil {
		return "", fmt.Errorf("failed to download %#q: %w", f.Location, err)
	}
	logrus.Debugf("res.ValidatedDigest=%v", res.ValidatedDigest)
	switch res.Status {
	case downloader.StatusDownloaded:
		logrus.Infof("Downloaded %s from %#q", description, f.Location)
	case downloader.StatusUsedCache:
		logrus.Infof("Using cache %#q", res.CachePath)
	default:
		logrus.Warnf("Unexpected result from downloader.Download(): %+v", res)
	}
	return res.CachePath, nil
}

// CachedFile checks if a file is in the cache, validating the digest if it is available. Returns path in cache.
func CachedFile(f limatype.File) (string, error) {
	res, err := downloader.Cached(f.Location,
		downloader.WithCache(),
		downloader.WithExpectedDigest(f.Digest))

View on GitHub (pinned to dd909d0973)

Solutions

  1. Inspect the wrapped cause for the concrete HTTP/network error
  2. Verify the URL in the template is reachable (curl -I the location)
  3. Fix network/proxy settings (HTTPS_PROXY etc.) and retry
  4. Update the template to a valid current release URL; check the expected digest matches the artifact

Example fix

// before
# stale URL
location: "https://example.com/old-release/image.iso"
// after
location: "https://example.com/current-release/image.iso"
Defensive patterns

Strategy: retry

Validate before calling

// check reachability before invoking the flow
resp, err := http.Head(f.Location)
if err != nil || resp.StatusCode != http.StatusOK {
    return fmt.Errorf("location %s unreachable", f.Location)
}

Try / catch

path, err := fileutils.DownloadFile(ctx, dest, f, decompress, desc, arch, formats)
if err != nil {
    if strings.HasPrefix(err.Error(), "failed to download") {
        // retry with backoff; the wrapped cause says why it failed
        return retryDownload(ctx, f)
    }
    return err
}

Prevention

When it happens

Trigger: downloader.Download returns an error during DownloadFile — network unreachable, HTTP 404/403 on the file URL, TLS failures, disk full when writing cache, or canceled context.

Common situations: Offline or firewalled environments; stale template URLs pointing at removed releases; corporate proxy blocking the download; wrong digest in the file entry causing validation failure.

Related errors


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