{"record":{"id":"963a822b43075972","repo":"docker/compose","slug":"s-is-not-a-compose-project-oci-artifact-but-s","errorCode":null,"errorMessage":"%s is not a compose project OCI artifact, but %s","messagePattern":"(.+?) is not a compose project OCI artifact, but (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/oci.go","lineNumber":208,"sourceCode":"\t\t\t}\n\t\t}\n\t\tg.known[path] = local\n\t}\n\treturn filepath.Join(local, \"compose.yaml\"), nil\n}\n\nfunc (g *ociRemoteLoader) Dir(path string) string {\n\treturn g.known[path]\n}\n\nfunc (g *ociRemoteLoader) pullComposeFiles(ctx context.Context, local string, manifest spec.Manifest, ref reference.Named, resolver remotes.Resolver) error {\n\terr := os.MkdirAll(local, 0o700)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif (manifest.ArtifactType != \"\" && manifest.ArtifactType != oci.ComposeProjectArtifactType) ||\n\t\t(manifest.ArtifactType == \"\" && manifest.Config.MediaType != oci.ComposeEmptyConfigMediaType) {\n\t\treturn fmt.Errorf(\"%s is not a compose project OCI artifact, but %s\", ref.String(), manifest.ArtifactType)\n\t}\n\n\tfor i, layer := range manifest.Layers {\n\t\tcontent, err := oci.GetBlob(ctx, resolver, ref, layer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tswitch layer.MediaType {\n\t\tcase oci.ComposeYAMLMediaType:\n\t\t\tif err := writeComposeFile(layer, i, local, content); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase oci.ComposeEnvFileMediaType:\n\t\t\tif err := writeEnvFile(layer, local, content); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase oci.ComposeEmptyConfigMediaType:","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/remote/oci.go#L190-L226","documentation":"pullComposeFiles validates the fetched manifest before extracting layers: either manifest.ArtifactType is set and must equal oci.ComposeProjectArtifactType, or — when it is empty — manifest.Config.MediaType must be the compose empty-config media type. Anything else means the manifest is not a compose project artifact, and the message reports the ref and the offending artifact type.","triggerScenarios":"A manifest whose ArtifactType is a foreign value (e.g. application/vnd.example.something) or whose config media type is a normal image config (application/vnd.oci.image.config.v1+json) when ArtifactType is empty. Reached when the top-level descriptor is a single manifest (not an index), or after fetching the compose-flagged manifest from an index.","commonSituations":"Pointing compose at a plain container image manifest rather than a bundle; bundles produced by non-docker tooling that uses its own artifact types; partially migrated images that have a compose layer but standard config media type.","solutions":["Inspect the manifest (`docker buildx imagetools inspect <ref> --raw`) and check artifactType/config.mediaType against what docker compose publishes.","Re-push the resource as a compose bundle with `docker compose push` from a supported compose version so the correct artifact/config types are set.","If the resource is a normal image, stop using it via oci:// in -f and reference it as a service image instead."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// when building bundles yourself, assert the manifest type before publishing\nif manifest.ArtifactType != \"\" && manifest.ArtifactType != ComposeProjectArtifactType {\n    return fmt.Errorf(\"refusing to publish %q as a compose bundle\", manifest.ArtifactType)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build compose bundles only with supported compose versions so artifact/config types are correct.","When hand-assembling bundles with oras/crane, set artifactType to the compose project type or the config media type to the compose empty-config type.","Inspect manifests with buildx imagetools before distributing."],"tags":["go","docker-compose","oci","validation","user-error"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}