docker/compose · error

OCI index %s doesn't refer to compose artifacts

Error message

OCI index %s doesn't refer to compose artifacts

What it means

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.

Source

Thrown at pkg/remote/oci.go:175

					return "", err
				}
				found := false
				for _, manifest := range index.Manifests {
					if manifest.ArtifactType != oci.ComposeProjectArtifactType {
						continue
					}
					found = true
					digested, err := reference.WithDigest(ref, manifest.Digest)
					if err != nil {
						return "", err
					}
					descriptor, content, err = oci.Get(ctx, resolver, digested)
					if err != nil {
						return "", fmt.Errorf("failed to pull OCI resource %q: %w", ref, err)
					}
				}
				if !found {
					return "", fmt.Errorf("OCI index %s doesn't refer to compose artifacts", ref)
				}
			}

			var manifest spec.Manifest
			err = json.Unmarshal(content, &manifest)
			if err != nil {
				return "", err
			}

			err = g.pullComposeFiles(ctx, local, manifest, ref, resolver)
			if err != nil {
				// we need to clean up the directory to be sure we won't leave empty files behind
				_ = os.RemoveAll(local)
				return "", err
			}
		}
		g.known[path] = local
	}

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Confirm the target is actually a compose bundle: `docker buildx imagetools inspect <ref>` and check for manifests with the com.docker.compose artifact type.
  2. If you meant to run a regular image, remove it from -f and use it under `image:` in a local compose file instead.
  3. Re-publish the bundle using a current docker compose version so the index manifests carry the compose ArtifactType.

Example fix

# before
docker compose -f oci://registry.example.com/nginx:latest up
# after: plain images belong in the model, not -f
# docker-compose.yml
services:
  web:
    image: registry.example.com/nginx:latest
Defensive patterns

Strategy: validation

Validate before calling

// confirm the ref is a compose bundle index before pointing -f at it
// (shell level, using buildx)
// docker buildx imagetools inspect <ref> --raw | grep -q 'compose.project' || echo "not a compose bundle"

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/9bd45dfaea2073a7. Report an issue: GitHub.