Skip to content

Inconsistent media type handling during manifest pushes

Context

While working on a workaround for #407 (closed), I realized that the way we're handling media types during manifest pushes is inconsistent and misleading.

Problem

  • We've deprecated and removed support for schema 1 manifests a while ago, but we're still defaulting to the schema 1 parser when no Content-Type media type is provided, which leads to obscure and misleading missing signature key errors;

  • There is no consistency in error messages for all possible combinations of payload and Content-Type media types. In !712 (merged), we have introduced a series of tests to cover this part of the API functionality. We should now review the current behavior and decide how we want to proceed.

Current behavior

For brevity, we will refer to the following media types in this table:

  • schema2: application/vnd.docker.distribution.manifest.v2+json
  • oci: application/vnd.oci.image.manifest.v1+json
  • unknown: application/vnd.foo.manifest.v1+json
Payload (manifest JSON) media type Content-Type request header media type Status code Error detail Notes
schema2 schema2 201 Created N.A.
schema2 400 Bad Request missing signature key Defaults to schema 1 parser.
schema2 400 Bad Request mediaType in manifest should be 'schema2' not ''
oci oci 201 Created N.A.
oci 400 Bad Request missing signature key Defaults to schema 1 parser.
oci 201 Created N.A.
400 Bad Request missing signature key Defaults to schema 1 parser.
schema2 oci 400 Bad Request if present, mediaType in manifest should be 'oci' not 'schema2'
oci schema2 400 Bad Request mediaType in manifest should be 'schema2' not 'oci'
unknown schema2 400 Bad Request mediaType in manifest should be 'schema2' not 'unknown'
unknown oci 400 Bad Request if present, mediaType in manifest should be 'oci' not 'unknown'
unknown unknown 400 Bad Request missing signature key Defaults to schema 1 parser.
unknown 400 Bad Request missing signature key Defaults to schema 1 parser.

Proposal

We need to:

  1. Stop defaulting to the schema 1 parser, as we have already deprecated and removed support for schema 1 manifests;
  2. Choose a new default parser;
  3. The behavior should be consistent.

I did some tests against GCR and ECR to see how they behave with the above combination of media types and described my findings in #426 (comment 641993145) and #426 (comment 642025800), respectively. ECR behaved in a weird way, rejecting many combinations with a 401 Unauthorized response. GCR behaves similar to us, but defaults to schema 2. I think we should do the same.

Based on this, the proposal is to modify the above behavior into the following:

Payload (manifest JSON) media type Content-Type request header media type Status code Error detail Notes
schema2 schema2 201 Created N.A.
schema2 201 Created N.A. Different status code and error detail.
schema2 400 Bad Request no mediaType in manifest Different error detail.
oci oci 201 Created N.A.
oci 400 Bad Request mediaType in manifest should be 'schema2' not 'oci' Different error detail.
oci 201 Created N.A.
400 Bad Request no mediaType in manifest Different error detail.
schema2 oci 400 Bad Request if present, mediaType in manifest should be 'oci' not 'schema2'
oci schema2 400 Bad Request mediaType in manifest should be 'schema2' not 'oci'
unknown schema2 400 Bad Request mediaType in manifest should be 'schema2' not 'unknown'
unknown oci 400 Bad Request if present, mediaType in manifest should be 'oci' not 'unknown'
unknown unknown 400 Bad Request mediaType in manifest should be 'schema2' not 'unknown' Different error detail.
unknown 400 Bad Request mediaType in manifest should be 'schema2' not 'unknown' Different error detail.

Next Steps

Once we're done with manifests, we should do a similar exercise for manifest lists/indexes.

Edited by João Pereira