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
- Validate the digest before use: d, err := digest.Parse(s) — this rejects malformed algorithms early with a clearer error
- Use only supported algorithms (sha256, sha512) in configuration; fix typos in the digest string
- Ensure digests come from trusted sources (upstream metadata) rather than arbitrary user input
- 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
- Always construct digests with digest.Parse or digest.FromBytes, never by casting strings
- Validate digests when loading config/templates, not at download time
- Restrict allowed algorithms to sha256/sha512 in your config layer
- Treat external/user-supplied digests as untrusted input and validate early
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
- failed to calculate digest of raw image: %w
- local files are not cached
- path is empty
- expected an absolute path, got a relative path: %#q
- network %#q is not defined
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/efad35e1d9ca45ec.
Report an issue: GitHub.