containerd/containerd · error
failed to resolve layers: %w
Error message
failed to resolve layers: %w
What it means
resolveLayers failed while mapping each layer filename in the manifest to an ingested blob descriptor and preparing content-store filters. The wrapped inner error carries the real cause (e.g. 'layer %q not found', media-type detection failures, or store walk errors). ImportIndex wraps it to attribute the failure to layer resolution for the current manifest.
Source
Thrown at core/images/archive/importer.go:172
}
blobs[name] = desc
}
idx := ocispec.Index{
Versioned: specs.Versioned{
SchemaVersion: 2,
},
}
for _, mfst := range mfsts {
config, ok := blobs[mfst.Config]
if !ok {
return ocispec.Descriptor{}, fmt.Errorf("image config %q not found", mfst.Config)
}
config.MediaType = images.MediaTypeDockerSchema2Config
layers, err := resolveLayers(ctx, store, mfst.Layers, blobs, iopts.compress)
if err != nil {
return ocispec.Descriptor{}, fmt.Errorf("failed to resolve layers: %w", err)
}
manifest := struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType"`
Config ocispec.Descriptor `json:"config"`
Layers []ocispec.Descriptor `json:"layers"`
}{
SchemaVersion: 2,
MediaType: images.MediaTypeDockerSchema2Manifest,
Config: config,
Layers: layers,
}
desc, err := writeManifest(ctx, store, manifest, manifest.MediaType)
if err != nil {
return ocispec.Descriptor{}, fmt.Errorf("write docker manifest: %w", err)
}View on GitHub (pinned to 4246446a2b)
Solutions
- Read the wrapped cause: if it says layer not found, fix the archive so every manifest.json Layers path exists in the tar
- If the cause is a store error, check containerd content store health and disk space (`ctr content ls`, df)
- Re-export the image with docker save or skopeo to get a clean archive
- Verify layer compression (gzip/zstd/none) is standard and supported
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate that every manifest.json Layers path exists in the tar
for _, m := range mfsts {
for _, l := range m.Layers {
if !contains(tarFiles, l) { return fmt.Errorf("layer %s missing", l) }
}
} Try / catch
if err := client.Import(ctx, reader); err != nil {
if strings.Contains(err.Error(), "failed to resolve layers") {
log.Errorf("layer resolution failed: %v", errors.Unwrap(err))
// branch on the wrapped cause (missing layer vs store error)
}
return err
} Prevention
- Unwrap errors.Unwrap / %w chain to find the root cause before acting
- Ensure the content store has free disk space and is healthy before large imports
- Use standard tooling (docker save, skopeo) to produce archives
- Set generous context timeouts for big images
When it happens
Trigger: ImportIndex calls resolveLayers(ctx, store, mfst.Layers, blobs, compress) and it returns an error: a listed layer file is absent from blobs, the content-store Walk with LabelUncompressed filters fails, or detectLayerMediaType/ReaderAt/DecompressStream errors occur inside.
Common situations: Archives with truncated layer lists after manual editing; content store out of space or corrupted causing Walk/ReaderAt failures; layers stored as symlinks with missing targets; unusual compression formats the decompressor cannot sniff.
Related errors
- unrecognized image format
- missing index.json in OCI layout %s
- no target for symlink layer from %q to %q
- image config %q not found
- write docker manifest: %w
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/91868888f7d6da75.
Report an issue: GitHub.