{"record":{"id":"d3d4fb247f027d47","repo":"docker/cli","slug":"manifest-s-must-have-an-os-and-architecture-to-be","errorCode":null,"errorMessage":"manifest %s must have an OS and Architecture to be pushed to a registry","messagePattern":"manifest (.+?) must have an OS and Architecture to be pushed to a registry","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/manifest/push.go","lineNumber":131,"sourceCode":"\n\t\t\tmanifestPush, err := buildPutManifestRequest(imageManifest, targetRef)\n\t\t\tif err != nil {\n\t\t\t\treturn req, err\n\t\t\t}\n\t\t\treq.mountRequests = append(req.mountRequests, manifestPush)\n\t\t}\n\t}\n\treturn req, nil\n}\n\nfunc buildManifestList(manifests []types.ImageManifest, targetRef reference.Named) (*manifestlist.DeserializedManifestList, error) {\n\ttargetRepo := reference.TrimNamed(targetRef)\n\tdescriptors := make([]manifestlist.ManifestDescriptor, 0, len(manifests))\n\tfor _, imageManifest := range manifests {\n\t\tif imageManifest.Descriptor.Platform == nil ||\n\t\t\timageManifest.Descriptor.Platform.Architecture == \"\" ||\n\t\t\timageManifest.Descriptor.Platform.OS == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"manifest %s must have an OS and Architecture to be pushed to a registry\", imageManifest.Ref)\n\t\t}\n\t\tdescriptor, err := buildManifestDescriptor(targetRepo, imageManifest)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdescriptors = append(descriptors, descriptor)\n\t}\n\n\treturn manifestlist.FromDescriptors(descriptors)\n}\n\nfunc buildManifestDescriptor(targetRepo reference.Named, imageManifest types.ImageManifest) (manifestlist.ManifestDescriptor, error) {\n\tmanifestRepoHostname := reference.Domain(reference.TrimNamed(imageManifest.Ref))\n\ttargetRepoHostname := reference.Domain(reference.TrimNamed(targetRepo))\n\tif manifestRepoHostname != targetRepoHostname {\n\t\treturn manifestlist.ManifestDescriptor{}, fmt.Errorf(\"cannot use source images from a different registry than the target image: %s != %s\", manifestRepoHostname, targetRepoHostname)\n\t}\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/manifest/push.go#L113-L149","documentation":"Returned by `buildManifestList` (push.go:127-132) when a constituent manifest has `Descriptor.Platform == nil` or an empty OS/Architecture. A registry requires every manifest-list entry to declare a platform, so the push is aborted before any network call. This happens when an image was added without annotation and its source manifest lacked platform metadata.","triggerScenarios":"Running `docker manifest create list img` where `img` is a single-arch image whose manifest has no platform, then `docker manifest push list` without annotating --os/--arch.","commonSituations":"Forgetting `docker manifest annotate --os --arch` after create, or adding an image from a registry that omits platform fields.","solutions":["Annotate each offending entry: `docker manifest annotate --os linux --arch amd64 list img`.","Re-create the list using images that carry platform metadata.","Inspect each member to find which one is missing platform info.","Push each single-arch image separately if a manifest list is not required."],"exampleFix":"# before\ndocker manifest create mylist img-no-platform\ndocker manifest push mylist        # fails\n# after\ndocker manifest annotate mylist img-no-platform --os linux --arch amd64\ndocker manifest push mylist","handlingStrategy":"validation","validationCode":"// verify every member has platform metadata before pushing\nfor _, m := range manifests {\n    if m.Descriptor.Platform == nil ||\n        m.Descriptor.Platform.OS == \"\" ||\n        m.Descriptor.Platform.Architecture == \"\" {\n        return fmt.Errorf(\"member %s missing OS/Architecture; annotate before push\", m.Ref)\n    }\n}","typeGuard":"func hasPlatform(m types.ImageManifest) bool {\n    p := m.Descriptor.Platform\n    return p != nil && p.OS != \"\" && p.Architecture != \"\"\n}","tryCatchPattern":"if err := runPush(ctx, cli, opts); err != nil {\n    if strings.Contains(err.Error(), \"must have an OS and Architecture\") {\n        // identify and annotate the offending member\n        return annotateMissingPlatforms(manifests)\n    }\n    return err\n}","preventionTips":["Annotate every member with --os/--arch after create.","Use source images that already carry platform metadata.","Inspect each member before push to catch empty platforms."],"tags":["manifest","push","platform","annotation","registry","docker-cli"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}