docker/cli · error

invalid manifest file

Error message

invalid manifest file %v: image manifest digest mismatch (%v != %v)

What it means

Returned by fsStore.getFromFilename (manifest/store/store.go:76) during the backward-compatibility path for manifests serialized with the deprecated Digest field. It recomputes the digest of the payload and compares it to the stored Digest; a mismatch means the on-disk manifest file is corrupt or was tampered with. The format prints filename, stored digest, and recomputed digest.

Solutions

  1. Delete the stale manifest cache entry: `rm -rf ~/.docker/manifests/<encoded-list-ref>` then re-run the manifest command to re-fetch.
  2. If you maintain the file manually, re-serialize with the correct Descriptor and remove the legacy Digest/Platform fields so the compat path is skipped.
  3. Run `docker manifest rm <list-ref>` (which calls Store.Remove) to clear the transaction and retry.
  4. Verify disk integrity (fsck) if files keep becoming corrupt.

Example fix

// before: reading a possibly-corrupt cached manifest
im, err := s.Get(listRef, manifestRef)

// after: on mismatch, purge the cache and fall through to re-fetch
if err != nil {
    if strings.Contains(err.Error(), "digest mismatch") {
        _ = s.Remove(listRef)
        im, err = s.Get(listRef, manifestRef)
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

// On digest mismatch, purge the stale cache entry and re-fetch
im, err := s.Get(listRef, manifestRef)
if err != nil && strings.Contains(err.Error(), "digest mismatch") {
    _ = s.Remove(listRef)
    im, err = s.Get(listRef, manifestRef)
}
if err != nil { return err }

Prevention

When it happens

Trigger: Calling store.Get or store.GetList on a manifest list whose cached JSON file on disk (under ~/.docker/manifests/) contains the legacy `Digest` field but the recomputed digest of the manifest payload no longer equals it. This happens if the file was hand-edited, partially overwritten, truncated by a crash, or migrated incorrectly between docker versions.

Common situations: Editing ~/.docker/manifests files by hand, disk corruption, a killed `docker manifest`/`docker buildx` process that left a half-written file, or a cross-platform copy that altered line endings so the payload bytes differ from the hashed bytes.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/15d624626c89286c. Report an issue: GitHub.

Appendix: source

Thrown at cli/manifest/store/store.go:76

		// Deprecated Fields, replaced by Descriptor
		Digest   digest.Digest
		Platform *manifestlist.PlatformSpec
	}

	if err := json.Unmarshal(bytes, &manifestInfo); err != nil {
		return types.ImageManifest{}, err
	}

	// Compatibility with image manifests created before
	// descriptor, newer versions omit Digest and Platform
	if manifestInfo.Digest != "" {
		mediaType, raw, err := manifestInfo.Payload()
		if err != nil {
			return types.ImageManifest{}, err
		}
		if dgst := digest.FromBytes(raw); dgst != manifestInfo.Digest {
			return types.ImageManifest{}, fmt.Errorf("invalid manifest file %v: image manifest digest mismatch (%v != %v)", filename, manifestInfo.Digest, dgst)
		}
		manifestInfo.ImageManifest.Descriptor = ocispec.Descriptor{
			Digest:    manifestInfo.Digest,
			Size:      int64(len(raw)),
			MediaType: mediaType,
			Platform:  types.OCIPlatform(manifestInfo.Platform),
		}
	}

	return manifestInfo.ImageManifest, nil
}

// GetList returns all the local manifests for a transaction
func (s *fsStore) GetList(listRef reference.Reference) ([]types.ImageManifest, error) {
	filenames, err := s.listManifests(listRef.String())
	switch {
	case err != nil:
		return nil, err

View on GitHub (pinned to 4f84911bfe)