containerd/containerd · error
failed to get info from content store: %w
Error message
failed to get info from content store: %w
What it means
This error is returned by the EROFS differ's Compare method when the underlying containerd content store lookup fails. After opening the layer blob, Compare calls s.store.Info(ctx, dgst) to fetch metadata for the diff's digest; any error from the content store (blob missing, backend failure, cancelled context) is wrapped with this message and Compare returns an empty descriptor.
Source
Thrown at plugins/diff/erofs/compare_linux.go:172
}
}
var commitopts []content.Opt
if config.Labels != nil {
commitopts = append(commitopts, content.WithLabels(config.Labels))
}
dgst := cw.Digest()
if errOpen = cw.Commit(ctx, 0, dgst, commitopts...); errOpen != nil {
if !errdefs.IsAlreadyExists(errOpen) {
return emptyDesc, fmt.Errorf("failed to commit: %w", errOpen)
}
errOpen = nil
}
info, err := s.store.Info(ctx, dgst)
if err != nil {
return emptyDesc, fmt.Errorf("failed to get info from content store: %w", err)
}
if info.Labels == nil {
info.Labels = make(map[string]string)
}
// Set "containerd.io/uncompressed" label if digest already existed without label
if _, ok := info.Labels[labels.LabelUncompressed]; !ok {
info.Labels[labels.LabelUncompressed] = config.Labels[labels.LabelUncompressed]
if _, err := s.store.Update(ctx, info, "labels."+labels.LabelUncompressed); err != nil {
return emptyDesc, fmt.Errorf("error setting uncompressed label: %w", err)
}
}
return ocispec.Descriptor{
MediaType: config.MediaType,
Size: info.Size,
Digest: info.Digest,
}, nil
}View on GitHub (pinned to 4246446a2b)
Solutions
- Verify the blob exists in the content store: `ctr -n <namespace> content ls` or `ctr content get <dgst>`; re-pull the image if it is missing.
- Check that the Compare call runs in the same namespace as the store that holds the blob.
- Check content store backend health (bolt DB file, disk space, permissions) and inspect daemon logs for the underlying wrapped error.
- If blobs are being evicted, raise GC limits or re-pull the image before calling Compare.
Example fix
// before: assuming the layer blob is local
meta, err := differ.Compare(ctx, layerDesc, mounts, opts...)
// after: ensure the blob is present before comparing
if _, err := client.ContentStore().Info(ctx, layerDesc.Digest); err != nil {
if err := client.Fetch(ctx, container, layerDesc); err != nil { return err }
}
meta, err := differ.Compare(ctx, layerDesc, mounts, opts...) Defensive patterns
Strategy: validation
Validate before calling
cs := client.ContentStore()
if _, err := cs.Info(ctx, desc.Digest); err != nil {
// blob missing locally; fetch it before calling Compare
if err := client.Fetch(ctx, container, desc); err != nil { return fmt.Errorf("blob %s unavailable: %w", desc.Digest, err) }
} Type guard
func blobInStore(ctx context.Context, cs contentstore.ContentStore, dgst digest.Digest) bool {
_, err := cs.Info(ctx, dgst)
return err == nil
} Try / catch
desc, err := differ.Compare(ctx, layerDesc, mounts, opts...)
if err != nil && strings.Contains(err.Error(), "failed to get info from content store") {
// re-pull the image / restore the blob, then retry once
if rerr := repull(ctx, ref); rerr == nil { desc, err = differ.Compare(ctx, layerDesc, mounts, opts...) }
} Prevention
- Check the blob's presence via ContentStore().Info before diff operations.
- Avoid aggressive GC settings that evict blobs still needed for diffs.
- Keep Compare calls in the same containerd namespace that owns the content.
- Monitor content store health and disk space; treat bolt DB corruption alerts as urgent.
When it happens
Trigger: Calling Compare (via the diff service or on snapshot commit) with a digest that is not present in the local content store; a content store backend (e.g. bolt metadata or blob store) I/O failure; ctx cancelled before Info completes; a garbage-collected blob whose digest is still referenced.
Common situations: Layers pruned by automatic GC before the diff is computed; pulling with content disabled or partial (lazy/remote) content so the blob was never materialized locally; corrupted content store DB after an unclean shutdown; referencing a digest from a different containerd namespace than the one the store is opened with.
Related errors
- failed to get reader: %w
- error setting uncompressed label: %w
- unsupported media type: %s
- failed to open writer: %w
- writer has been reset
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/2c421b4352eabd92.
Report an issue: GitHub.