docker/compose · error
unsupported OCI version: %s
Error message
unsupported OCI version: %s
What it means
When pushing a compose project as an OCI artifact, push.go builds a manifest according to the requested OCI compat version and only knows how to lay out 1.0 (config layer with project bytes, empty artifactType) and 1.1 (empty-JSON config descriptor plus ComposeProjectArtifactType). Any other value in the version variable hits the default arm and is rejected before any network I/O.
Source
Thrown at internal/oci/push.go:194
// tooling falls back to the config media type, so this is used to
// indicate that it's not a container image but custom content.
configData := []byte("{}")
config = v1.Descriptor{
MediaType: ComposeEmptyConfigMediaType,
Digest: digest.FromBytes(configData),
Size: int64(len(configData)),
Data: configData,
}
// N.B. OCI 1.0 does NOT support specifying the artifact type, so it's
// left as an empty string to omit it from the marshaled JSON
artifactType = ""
toPush = append(toPush, config)
case api.OCIVersion1_1:
config = v1.DescriptorEmptyJSON
artifactType = ComposeProjectArtifactType
toPush = append(toPush, config)
default:
return v1.Descriptor{}, nil, fmt.Errorf("unsupported OCI version: %s", ociCompat)
}
manifest, err := json.Marshal(v1.Manifest{
Versioned: specs.Versioned{SchemaVersion: 2},
MediaType: v1.MediaTypeImageManifest,
ArtifactType: artifactType,
Config: config,
Layers: layers,
Annotations: map[string]string{
"org.opencontainers.image.created": time.Now().Format(time.RFC3339),
},
})
if err != nil {
return v1.Descriptor{}, nil, err
}
manifestDescriptor := v1.Descriptor{
MediaType: v1.MediaTypeImageManifest,View on GitHub (pinned to ddc4b044b6)
Solutions
- Use one of the supported constants (api.OCIVersion1_1 for modern registries, api.OCIVersion1_0 for strict 1.0 registries).
- If you introduced a new version constant, add a case to the switch in push.go mapping it to the right config/artifactType layout.
- Validate the version at the CLI/config boundary so unhandled values fail with a clear message before push starts.
- Check which values your compose build supports: grep for OCIVersion in internal/api.
Example fix
// before (caller) ociCompat := "1.2" // unhandled by push.go // after (caller) ociCompat := api.OCIVersion1_1 // or api.OCIVersion1_0
Defensive patterns
Strategy: validation
Validate before calling
switch ociCompat {
case api.OCIVersion1_0, api.OCIVersion1_1:
default:
return fmt.Errorf("unsupported OCI version %q; use %s or %s", ociCompat, api.OCIVersion1_0, api.OCIVersion1_1)
} Type guard
func supportedOCIVersion(v api.OCIVersion) bool {
return v == api.OCIVersion1_0 || v == api.OCIVersion1_1
} Prevention
- Only use the api package's OCIVersion constants.
- Validate the version at flag-parsing time, before push begins.
- When adding a version constant, extend the push.go switch in the same change.
When it happens
Trigger: Calling the artifact push path with an ociCompat value other than api.OCIVersion1_0/OCIVersion1_1 — typically a new constant added to the API package without extending this switch, or a caller-supplied string parsed into an unhandled value (e.g. via a future --oci-compat variant flag).
Common situations: Version skew after adding a new OCI version constant to internal/api without updating push.go; tests iterating all api.OCIVersion* constants; hand-rolled callers passing a raw version string instead of the defined constants.
Related errors
- failed to pull OCI resource %q: %w
- creating fetcher for %s: %w
- fetching blob %s: %w
- reading blob %s: %w
- blob %s size mismatch: expected %d bytes, got %d
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/b58069d96b5bf647.
Report an issue: GitHub.