{"record":{"id":"0884a491546733e8","repo":"docker/cli","slug":"manifest-verification-failed-for-digest-s","errorCode":null,"errorMessage":"manifest verification failed for digest %s","messagePattern":"manifest verification failed for digest (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/registryclient/fetcher.go","lineNumber":147,"sourceCode":"\treturn configJSON, nil\n}\n\n// validateManifestDigest computes the manifest digest, and, if pulling by\n// digest, ensures that it matches the requested digest.\nfunc validateManifestDigest(ref reference.Named, mfst distribution.Manifest) (ocispec.Descriptor, error) {\n\tmediaType, canonical, err := mfst.Payload()\n\tif err != nil {\n\t\treturn ocispec.Descriptor{}, err\n\t}\n\tdesc := ocispec.Descriptor{\n\t\tDigest:    digest.FromBytes(canonical),\n\t\tSize:      int64(len(canonical)),\n\t\tMediaType: mediaType,\n\t}\n\n\t// If pull by digest, then verify the manifest digest.\n\tif digested, isDigested := ref.(reference.Canonical); isDigested && digested.Digest() != desc.Digest {\n\t\treturn ocispec.Descriptor{}, fmt.Errorf(\"manifest verification failed for digest %s\", digested.Digest())\n\t}\n\n\treturn desc, nil\n}\n\n// pullManifestList handles \"manifest lists\" which point to various\n// platform-specific manifests.\nfunc pullManifestList(ctx context.Context, ref reference.Named, repo distribution.Repository, mfstList manifestlist.DeserializedManifestList) ([]types.ImageManifest, error) {\n\tif _, err := validateManifestDigest(ref, mfstList); err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfos := make([]types.ImageManifest, 0, len(mfstList.Manifests))\n\tfor _, manifestDescriptor := range mfstList.Manifests {\n\t\tmanSvc, err := repo.Manifests(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/internal/registryclient/fetcher.go#L129-L165","documentation":"validateManifestDigest recomputes the manifest digest from its canonical payload. When you pull by digest (@sha256:...) and the computed digest differs from the one you requested, the manifest does not match — a sign of corruption, tampering, or a digest mismatch. Pulls by tag skip this check.","triggerScenarios":"Pulling a manifest by digest where the registry-returned manifest's recomputed digest does not equal the requested digest — wrong content served, transit corruption, or a hand-typed wrong digest.","commonSituations":"Digest copied incorrectly; registry serving stale/wrong content for the digest; content mutated by a proxy; manifest re-signed or repackaged under the same digest by mistake.","solutions":["Double-check the requested digest string for typos (length, algorithm prefix).","Re-pull from a trusted mirror to rule out in-flight corruption.","Re-push the image to refresh manifest and digest.","Inspect for a MITM/proxy modifying payloads; pin to content-trusted registries."],"exampleFix":"// before\nref, _ := reference.WithDigest(name, badDigest)\nc.GetManifest(ctx, ref) // -> manifest verification failed\n\n// after\nref, _ := reference.WithDigest(name, correctDigest) // copy digest exactly\nc.GetManifest(ctx, ref)","handlingStrategy":"validation","validationCode":"// Recompute and compare the manifest digest client-side before trusting it.\nfunc checkDigest(mfst distribution.Manifest, want digest.Digest) error {\n    _, canon, err := mfst.Payload()\n    if err != nil {\n        return err\n    }\n    if got := digest.FromBytes(canon); got != want {\n        return fmt.Errorf(\"digest mismatch: got %s want %s\", got, want)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy digests verbatim; verify length and algorithm prefix.","Pull from trusted registries and pin by digest.","Watch for proxies/CDNs that mutate content.","Re-push images when digests drift."],"tags":["docker","registry","integrity","security","digest"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}