{"record":{"id":"6dc49a17d9fbbf8a","repo":"docker/cli","slug":"failed-to-put-manifest-s-w","errorCode":null,"errorMessage":"failed to put manifest %s: %w","messagePattern":"failed to put manifest (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/registryclient/client.go","lineNumber":117,"sourceCode":"\trepoEndpoint.actions = []string{\"pull\", \"push\"}\n\trepo, err := c.getRepositoryForReference(ctx, ref, repoEndpoint)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmanifestService, err := repo.Manifests(ctx)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t_, opts, err := getManifestOptionsFromReference(ref)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdgst, err := manifestService.Put(ctx, manifest, opts...)\n\tif err != nil {\n\t\treturn dgst, fmt.Errorf(\"failed to put manifest %s: %w\", ref, err)\n\t}\n\treturn dgst, nil\n}\n\nfunc (c *client) getRepositoryForReference(ctx context.Context, ref reference.Named, repoEndpoint repositoryEndpoint) (distribution.Repository, error) {\n\trepoName, err := reference.WithName(repoEndpoint.repoName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse repo name from %s: %w\", ref, err)\n\t}\n\thttpTransport, err := c.getHTTPTransportForRepoEndpoint(ctx, repoEndpoint)\n\tif err != nil {\n\t\tif !strings.Contains(err.Error(), \"server gave HTTP response to HTTPS client\") {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !repoEndpoint.endpoint.TLSConfig.InsecureSkipVerify {\n\t\t\treturn nil, httpProtoError{cause: err}\n\t\t}\n\t\t// --insecure was set; fall back to plain HTTP","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/internal/registryclient/client.go#L99-L135","documentation":"Returned by client.PutManifest when manifestService.Put (distribution Put) returns a non-nil error while uploading a manifest to the registry. The reference and underlying error are wrapped with %w. This is the final step of pushing an image manifest.","triggerScenarios":"Pushing a manifest (PutManifest) when the registry rejects the PUT — manifest invalid/unknown schema, missing referenced blobs/layers, digest mismatch, authorization denied, name/tag validation error, or transport failure.","commonSituations":"Pushing a manifest before its layers are uploaded; tag naming violation (uppercase, _ vs .); registry quota/permission denied; manifest schema unsupported by registry; network error mid-upload.","solutions":["Ensure all referenced blobs/layers are already pushed to the target repository.","Inspect the wrapped error: 401/403 -> auth, 400 -> manifest/tag format, 4xx -> schema.","Use a valid reference (lowercase repo, allowed tag chars).","Retry on transient transport failures."],"exampleFix":"// before: layers not uploaded first\nclient.PutManifest(ctx, ref, manifest)  // 400 manifest blob unknown\n// after: push layers, then manifest\nclient.MountBlob(ctx, layerSrc, ref)      // or UploadBlob\nclient.PutManifest(ctx, ref, manifest)","handlingStrategy":"try-catch","validationCode":"// ensure all manifest descriptors' blobs exist before Put\nfor _, d := range manifest.References() {\n    if _, err := repo.Blobs(ctx).Stat(ctx, d.Digest); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":"if errdefs.IsUnauthorized(err) { refreshCreds(); retry }\nif errdefs.IsInvalidParameter(err) { fixManifestOrRef() }","preventionTips":["Upload all referenced layers/digests before the manifest.","Validate repo/tag naming (lowercase, allowed chars).","Classify via the wrapped error before retrying."],"tags":["registry","manifest","push","distribution","docker"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}