{"record":{"id":"cbec1e92604be028","repo":"docker/cli","slug":"image-config-verification-failed-for-digest-s","errorCode":null,"errorMessage":"image config verification failed for digest %s","messagePattern":"image config verification failed for digest (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/registryclient/fetcher.go","lineNumber":127,"sourceCode":"\t\treturn types.ImageManifest{}, err\n\t}\n\n\treturn types.NewOCIImageManifest(ref, manifestDesc, &mfst), nil\n}\n\nfunc pullManifestSchemaV2ImageConfig(ctx context.Context, dgst digest.Digest, repo distribution.Repository) ([]byte, error) {\n\tblobs := repo.Blobs(ctx)\n\tconfigJSON, err := blobs.Get(ctx, dgst)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tverifier := dgst.Verifier()\n\tif _, err := verifier.Write(configJSON); err != nil {\n\t\treturn nil, err\n\t}\n\tif !verifier.Verified() {\n\t\treturn nil, fmt.Errorf(\"image config verification failed for digest %s\", dgst)\n\t}\n\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.","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/internal/registryclient/fetcher.go#L109-L145","documentation":"After pulling the image config blob, a digest verifier recomputes the digest over the returned bytes and compares it to the digest the manifest referenced. A mismatch means the config bytes were corrupted in transit or in registry storage, or the manifest points at the wrong digest. The client deliberately refuses to trust unverifiable config.","triggerScenarios":"The config blob returned by the registry does not hash to the digest embedded in the manifest — registry storage bit-rot, a MITM altering bytes, a manifest republished with a stale config digest, or a partial/corrupted push.","commonSituations":"Corrupted registry backend; a transparent proxy re-encoding content; interrupted push leaving a manifest referencing a config that was never fully written; hardware/storage errors.","solutions":["Re-pull from a known-good mirror or another tag of the same image.","Re-build and re-push the image so manifest and config digests are consistent.","Check registry storage integrity and the push pipeline for partial writes.","Verify no proxy/CDN is altering byte payloads (compression, transcoding)."],"exampleFix":"# suspect corruption -> repush the image\ndocker build -t myreg/img:fix . && docker push myreg/img:fix\n# then pull the freshly-pushed tag","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// On config verification failure, retry once from a mirror before failing hard.\nif isConfigVerifyErr(err) {\n    if m, e2 := mirrorClient.GetManifest(ctx, ref); e2 == nil {\n        return m, nil\n    }\n}\nreturn err","preventionTips":["Pull from trusted, integrity-checked registries.","Pin images by digest so mismatches are caught.","Investigate any proxy that could alter blob bytes.","Re-push images whose manifest/config 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"}