lima-vm/lima · error

invalid digest algorithm %#q

Error message

invalid digest algorithm %#q

What it means

cacheDigestPath builds the digest file name "<ALGO>.digest" inside the cache directory, using the algorithm string from the expected digest. Because that string becomes a path component, it is validated to contain no path separators; an algorithm containing '/' or '\' is rejected with this error to prevent path traversal or invalid cache filenames.

Source

Thrown at pkg/downloader/downloader.go:617

}

// cacheDirectoryPath returns the cache subdirectory path.
//   - "url" file contains the url
//   - "data" file contains the data
//   - "time" file contains the time (Last-Modified header)
//   - "type" file contains the type (Content-Type header)
func cacheDirectoryPath(cacheDir, remote string) string {
	return filepath.Join(cacheDir, "download", "by-url-sha256", CacheKey(remote))
}

// cacheDigestPath returns the cache digest file path.
//   - "<ALGO>.digest" contains the digest
func cacheDigestPath(shad string, expectedDigest digest.Digest) (string, error) {
	shadDigest := ""
	if expectedDigest != "" {
		algo := expectedDigest.Algorithm().String()
		if strings.Contains(algo, "/") || strings.Contains(algo, "\\") {
			return "", fmt.Errorf("invalid digest algorithm %#q", algo)
		}
		shadDigest = filepath.Join(shad, algo+".digest")
	}
	return shadDigest, nil
}

func IsLocal(s string) bool {
	return !strings.Contains(s, "://") || strings.HasPrefix(s, "file://")
}

// canonicalLocalPath canonicalizes the local path string.
//   - Make sure the file has no scheme, or the `file://` scheme
//   - If it has the `file://` scheme, strip the scheme and make sure the filename is absolute
//   - Expand a leading `~`, or convert relative to absolute name
func canonicalLocalPath(s string) (string, error) {
	if s == "" {
		return "", errors.New("got empty path")
	}

View on GitHub (pinned to dd909d0973)

Solutions

  1. Validate the digest before use: d, err := digest.Parse(s) — this rejects malformed algorithms early with a clearer error
  2. Use only supported algorithms (sha256, sha512) in configuration; fix typos in the digest string
  3. Ensure digests come from trusted sources (upstream metadata) rather than arbitrary user input
  4. If the digest originates in a Lima template, correct the digests field to a valid "algo:hex" value

Example fix

// before
expected := digest.Digest(req.Digest) // "sha/256:abc..."
// after
expected, err := digest.Parse(req.Digest)
if err != nil {
    return fmt.Errorf("invalid digest %q: %w", req.Digest, err)
}
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/opencontainers/go-digest"
func validateDigest(s string) (digest.Digest, error) {
    d, err := digest.Parse(s) // rejects malformed algorithms before cacheDigestPath sees them
    if err != nil { return "", fmt.Errorf("invalid digest %q: %w", s, err) }
    if algo := d.Algorithm().String(); strings.ContainsAny(algo, "/\\") {
        return "", fmt.Errorf("unsupported algorithm %q", algo)
    }
    return d, nil
}

Type guard

func isSafeDigest(d digest.Digest) bool {
    if d == "" { return true }
    algo := d.Algorithm().String()
    return !strings.ContainsAny(algo, "/\\")
}

Try / catch

res, err := downloader.Download(url, downloader.WithExpectedDigest(d))
if err != nil && strings.Contains(err.Error(), "invalid digest algorithm") {
    return fmt.Errorf("digest from config is malformed; use digest.Parse at load time: %w", err)
}

Prevention

When it happens

Trigger: Passing WithExpectedDigest(digest.Digest) whose algorithm string contains a slash or backslash (e.g. a malformed digest string like "sha/x256:..." or a hand-built digest) to Download/Cached — raised from getCached, fetch, or Cached via cacheDigestPath.

Common situations: Digest strings built by hand or parsed from untrusted config instead of using go-digest's digest.Parse, which would have rejected them earlier; typos in a digest annotation in a template YAML.

Related errors


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