Container registry returns 200 OK instead of 201 Created for a successful manifest PUT #3250

Version: 16.9.7 and 17.2.0 (the code is unchanged on main at c1899e02c6)

Description

When a manifest is pushed to the built-in container registry (PUT /v2/<name>/manifests/<reference>), OneDev stores it and answers 200 OK. The OCI Distribution Specification requires 201 Created for this request:

Upon a successful upload, the registry MUST return response code 201 Created, and MUST have the following header: Location: <location> (distribution-spec v1.1.1, "Pushing Manifests")

The Location and Docker-Content-Digest headers are already present, so only the status code differs. Blob uploads already return 201 Created correctly.

Impact

Clients that follow the specification treat the response as a failure even though the manifest has been stored. oras exits with status 1 and reports:

Error response from registry: recognizable error message not found: PUT "http://<host>/v2/<project>/<repo>/manifests/v1": response status code 200: OK

oras-go accepts only 201 for a manifest push (registry/remote/repository.go). Docker, buildx and containerd accept 200, so ordinary image pushes do not show the problem.

Cause

server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java, line 381 in the manifest PUT branch:

response.setStatus(SC_OK);

Suggested fix

response.setStatus(SC_CREATED);

SC_CREATED is already imported in this file and used for blob uploads.

Steps to reproduce

  1. Start OneDev 17.2.0 (1dev/server:17.2.0) and create a project with package management enabled.
  2. Upload a config blob and one layer blob through POST /v2/<project>/<repo>/blobs/uploads/ followed by PUT <location>?digest=sha256:…. Both return 201 Created.
  3. PUT /v2/<project>/<repo>/manifests/v1 with Content-Type: application/vnd.oci.image.manifest.v1+json and an image manifest that references the two blobs.
  4. Observed: 200 OK. Expected: 201 Created.
  5. For comparison, the same requests against CNCF distribution 2.8.3 (registry:2) return 201 Created.
  6. oras push --plain-http <host>/<project>/<repo>:v1 file (oras 1.2.3) fails with the error above, yet GET /v2/<project>/<repo>/manifests/v1 returns the manifest.

The same result was observed on 16.9.7.

1/1
Type
Bug
Priority
Normal
Assignee
Affected Versions
17.2.0
Labels
No labels
Issue Votes (0)
Watchers (2)
Reference
OD-3250
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover