-
Notifications
You must be signed in to change notification settings - Fork 616
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
When using crane flatten on an image which has both an index manifest and the image itself using OCI media types, the resulting manifests ends up being a mix where the index still uses oci media types but the image manifest is using docker media types. This is creating issues with other tooling which seem to assume that the media type of the images manifest is going to be the same as the one from the index. Using this assumption, the tooling makes a call to the registry with the header http.request.contenttype=application/vnd.oci.image.manifest.v1+json which will create an error on the registry's side.
One such tooling being crane copy itself.
To Reproduce
- have a registry running somewhere, ex with distribution:
docker run -d -p 127.0.0.1:5000:5000 --name registry registry - create a simple dockerfile
$ cat ./Dockerfile
FROM scratch
WORKDIR /test
- build an image from it with OCI media types:
docker buildx build -t localhost:5000/image:oci --provenance=false --platform linux/amd64,linux/arm64 --push --output 'type=image,oci-mediatypes=true' . - image in registry with OCI media types:
$ crane manifest localhost:5000/image:oci
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:f105adfc9fcd2c9fca0fba9f9b1c6e25413fd35dccaed9c3648e639fa7f68d0b",
"size": 475,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:4c0b8b510c2816a7f339210683cee10ee0454bcb3d677db1de4fc7f5b8491e3d",
"size": 475,
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
$ crane manifest localhost:5000/image:oci --platform linux/amd64
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:62a62ae86da19caa1e478e9a80a8393cabb0bb4281a91707d88746f7341342cf",
"size": 423
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:e8a161d1a19602cf63998d9c8e5913acedb3ec2f31f0a3eddab33c3dd83a4f9e",
"size": 92
}
]
- flatten the image:
$ crane flatten -t localhost:5000/image:flatten localhost:5000/image:oci
2026/01/29 14:08:41 pushed blob: sha256:c7a44368e7719efe2cdd40c31b92ecb6331e812b9bfc0e3306b61a4b575b511a
2026/01/29 14:08:41 pushed blob: sha256:c7a44368e7719efe2cdd40c31b92ecb6331e812b9bfc0e3306b61a4b575b511a
2026/01/29 14:08:41 existing manifest: flatten@sha256:6c989990a3a4a814fa98f22812d90f722f80b076b60444f5babe2aa8f02a2a79
localhost:5000/image@sha256:6c989990a3a4a814fa98f22812d90f722f80b076b60444f5babe2aa8f02a2a79
- flattened index (OCI media types):
$ crane manifest localhost:5000/image:flatten | jq
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 422,
"digest": "sha256:bbfd1a68a7a297ec7814373e54760613fef52b3b414551ad719c72737ba88887",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 422,
"digest": "sha256:7209bc03699826a5708ff9089f65671c881a3050f086baacfea5946964201d8f",
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
- flattened image (Docker media types):
$ crane manifest localhost:5000/image:flatten --platform linux/amd64 | jq
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 585,
"digest": "sha256:2f4c2f06a12f7c2022ca6424049cce2277e79846baabf2e086d4b3d26352cb65"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 90,
"digest": "sha256:c7a44368e7719efe2cdd40c31b92ecb6331e812b9bfc0e3306b61a4b575b511a"
}
]
}
- try to copy the image in a new repository fails:
$ crane copy localhost:5000/image:flatten localhost:5000/new-image:flatten
2026/01/29 14:10:46 Copying from localhost:5000/image:flatten to localhost:5000/new-image:flatten
2026/01/29 14:10:46 existing blob: sha256:8b37ec0e4d19c87f32b1319f93af5f573fd4871ad7fe25abe76d52aa487b0ee6
2026/01/29 14:10:46 existing blob: sha256:c7a44368e7719efe2cdd40c31b92ecb6331e812b9bfc0e3306b61a4b575b511a
2026/01/29 14:10:46 existing blob: sha256:2f4c2f06a12f7c2022ca6424049cce2277e79846baabf2e086d4b3d26352cb65
Error: PUT http://localhost:5000/v2/new-image/manifests/sha256:bbfd1a68a7a297ec7814373e54760613fef52b3b414551ad719c72737ba88887: MANIFEST_INVALID: manifest invalid; if present, mediaType in manifest should be 'application/vnd.oci.image.manifest.v1+json' not 'application/vnd.docker.distribution.manifest.v2+json'
- from the registry logs, I think the issue is caused by the
contentTypeheader that crane copy uses to put the manifest:
time="2026-01-29T14:10:46.937561767Z" level=debug msg=PutImageManifest environment=development go.version=go1.23.7 http.request.contenttype=application/vnd.oci.image.manifest.v1+json http.request.host="localhost:5000" http.request.id=1db6985b-6b45-4fea-9c03-5d384a29539a http.request.method=PUT http.request.remoteaddr="172.17.0.1:39978" http.request.uri="/v2/new-image/manifests/sha256:bbfd1a68a7a297ec7814373e54760613fef52b3b414551ad719c72737ba88887" http.request.useragent="crane/0.19.1 go-containerregistry/0.19.1" instance.id=5ccaeee1-3d0b-4e92-8f25-a19ec1b2bcf3 service=registry vars.name=new-image vars.reference="sha256:bbfd1a68a7a297ec7814373e54760613fef52b3b414551ad719c72737ba88887" version=3.0.0
Expected behavior
I think there are 2 things I would expect there:
crane flattenshould keep the same media types used in the original image manifests. Which I think is just about using theold.Mediatypetherecrane copy: is it expected that thecontentTypeheader used when the image manifest is PUT doesn't match the actual mediaType used by the manifest?
Additional context
Add any other context about the problem here.
- Output of
crane version
$ crane version
0.20.7
- Registry used (e.g., GCR, ECR, Quay)
distribution registry
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working