containerd/containerd · error

unable to create manifests file: %w

Error message

unable to create manifests file: %w

What it means

Wraps a failure from manifestsRecord() while building the Docker-format manifests.json entry during a containerd image archive export (ctr images export / exporter.Export). When Docker manifests exist and skipDockerManifest is false, the exporter renders a tar record for manifests.json; any error reading manifests from the content store or encoding them is wrapped here. It means the export archive could not be fully assembled.

Source

Thrown at core/images/archive/exporter.go:345

			}
			if d != "" {
				if name := desc.Annotations[images.AnnotationImageName]; name != "" {
					mt := dManifests[d]
					mt.names = append(mt.names, name)
				}

			}
		} else {
			return fmt.Errorf("only manifests may be exported: %w", errdefs.ErrInvalidArgument)
		}
	}

	records = append(records, ociIndexRecord(slices.Concat(manifests, filterReferrers(records))))

	if !eo.skipDockerManifest && len(dManifests) > 0 {
		tr, err := manifestsRecord(ctx, store, dManifests)
		if err != nil {
			return fmt.Errorf("unable to create manifests file: %w", err)
		}

		records = append(records, tr)
	}

	if len(algorithms) > 0 {
		records = append(records, directoryRecord("blobs/", 0755))
		for alg := range algorithms {
			records = append(records, directoryRecord("blobs/"+alg+"/", 0755))
		}
	}

	tw := tar.NewWriter(writer)
	defer tw.Close()
	return writeTar(ctx, tw, records)
}

func getRecords(ctx context.Context, store content.Provider, desc ocispec.Descriptor, algorithms map[string]struct{}, brOpts *blobRecordOptions, referrers content.ReferrersProvider) ([]tarRecord, error) {

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Inspect the wrapped cause (%w) to find which manifest digest failed and repair the content store (re-pull the image: ctr images pull).
  2. Run ctr content verify or garbage-collect and re-fetch missing blobs to restore content-store integrity.
  3. Pass exporter.WithSkipDockerManifest (or use OCI-layout-only export) so manifestsRecord is not invoked, if the consumer supports OCI layout.
  4. Check disk space and permissions on the content store backing directory (blobs may be unreadable).

Example fix

// before
err := exporter.Export(ctx, tw, opts...)
// after (skip docker manifests if target accepts OCI layout)
err := exporter.Export(ctx, tw, append(opts, exporter.WithSkipDockerManifest(true))...)
Defensive patterns

Strategy: try-catch

Validate before calling

for _, d := range manifestDescriptors {
  if _, err := store.ReaderAt(ctx, d); err != nil {
    return fmt.Errorf("blob %s missing; re-pull image before export", d.Digest)
  }
}

Try / catch

if err := exporter.Export(ctx, tw, opts...); err != nil {
  var missing bool
  if strings.Contains(err.Error(), "not found") { missing = true }
  // missing => re-pull image and retry export
}

Prevention

When it happens

Trigger: Calling exporter.Export (or `ctr images export`) on a store where docker-format manifests reference blobs missing from the content store, or the manifest blobs are unreadable/corrupt, and skipDockerManifest is false so manifestsRecord runs.

Common situations: Exporting images whose content store was partially garbage-collected; exporting with a store missing docker-manifest-compatible entries; corrupted content store after interrupted pulls; exporting to old Docker consumers without disabling docker manifest generation.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/605afed833fa8f72. Report an issue: GitHub.