{"record":{"id":"9bd45dfaea2073a7","repo":"docker/compose","slug":"oci-index-s-doesn-t-refer-to-compose-artifacts","errorCode":null,"errorMessage":"OCI index %s doesn't refer to compose artifacts","messagePattern":"OCI index (.+?) doesn't refer to compose artifacts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/oci.go","lineNumber":175,"sourceCode":"\t\t\t\t\treturn \"\", err\n\t\t\t\t}\n\t\t\t\tfound := false\n\t\t\t\tfor _, manifest := range index.Manifests {\n\t\t\t\t\tif manifest.ArtifactType != oci.ComposeProjectArtifactType {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfound = true\n\t\t\t\t\tdigested, err := reference.WithDigest(ref, manifest.Digest)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn \"\", err\n\t\t\t\t\t}\n\t\t\t\t\tdescriptor, content, err = oci.Get(ctx, resolver, digested)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn \"\", fmt.Errorf(\"failed to pull OCI resource %q: %w\", ref, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !found {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"OCI index %s doesn't refer to compose artifacts\", ref)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar manifest spec.Manifest\n\t\t\terr = json.Unmarshal(content, &manifest)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\n\t\t\terr = g.pullComposeFiles(ctx, local, manifest, ref, resolver)\n\t\t\tif err != nil {\n\t\t\t\t// we need to clean up the directory to be sure we won't leave empty files behind\n\t\t\t\t_ = os.RemoveAll(local)\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t}\n\t\tg.known[path] = local\n\t}","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/remote/oci.go#L157-L193","documentation":"When the pulled descriptor is an image index, the loader iterates index.Manifests looking for entries with ArtifactType == oci.ComposeProjectArtifactType. If no manifest in the index has that artifact type, the bundle cannot contain compose files, so the loader rejects it explicitly. This distinguishes a valid-but-wrong image from a pull failure.","triggerScenarios":"Pointing the oci:// loader at an OCI image index that is a plain multi-arch image (container image manifests with application/vnd.docker.* or oci.image.manifest types and no compose artifactType), or a bundle built by a tool that did not set the compose artifact type on its manifests.","commonSituations":"Using -f oci://myregistry/app:v1 where app:v1 is a normal application image, not a compose bundle; publishing with an older/different compose version or a custom pusher that omits ArtifactType; copy-pasting a registry path meant for `docker run` into compose -f.","solutions":["Confirm the target is actually a compose bundle: `docker buildx imagetools inspect <ref>` and check for manifests with the com.docker.compose artifact type.","If you meant to run a regular image, remove it from -f and use it under `image:` in a local compose file instead.","Re-publish the bundle using a current docker compose version so the index manifests carry the compose ArtifactType."],"exampleFix":"# before\ndocker compose -f oci://registry.example.com/nginx:latest up\n# after: plain images belong in the model, not -f\n# docker-compose.yml\nservices:\n  web:\n    image: registry.example.com/nginx:latest","handlingStrategy":"validation","validationCode":"// confirm the ref is a compose bundle index before pointing -f at it\n// (shell level, using buildx)\n// docker buildx imagetools inspect <ref> --raw | grep -q 'compose.project' || echo \"not a compose bundle\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use oci:// paths with bundles created by `docker compose push`.","Keep application images under services.image, never under -f oci://.","Automate a bundle-type check in CI before promoting oci:// refs to environments."],"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"}