Skip to content

Copy artifact API replicates wrong tag when source artifact has multiple tags on the same digest #23706

Description

@oskisk

When using the copy artifact API to copy an artifact by a specific tag (e.g. :1.0.3), if the source artifact's digest is also tagged with another tag that was pushed more recently (e.g. :1.0.11), the triggered replication job replicates the wrong tag (1.0.11) instead of the requested one (1.0.3).

Steps to reproduce

  1. Push an image to a source project tagged as both 1.0.3 and 1.0.11 on the same digest, with 1.0.11 pushed after 1.0.3
  2. Configure a replication rule on the destination project
  3. Call the copy artifact API:
    POST /api/v2.0/projects/<dst-project>/repositories/<repo>/artifacts?from=<src-project>/<repo>:1.0.3
    
  4. Observe the triggered replication job, it copies :1.0.11 instead of :1.0.3

Expected behavior

The replication job copies tag 1.0.3 to the upstream registry.

Actual behavior

The replication job copies tag 1.0.11 (the most recently pushed tag on the same digest).

Root cause

In src/controller/artifact/controller.go, copyDeeply fetches the source artifact with all its tags via GetByReference(..., {WithTag: true}). Tags are sorted by PushTime DESC, so the most recently pushed tag appears first. The full tag list is passed to Ensure, which fires a single push event using option.Tags[0], the most recently pushed tag, ignoring which tag was specified in the copy request.

Fix

In copyDeeply, when the reference is a tag name, only include that specific tag in the list passed to Ensure so the push event fires with the correct tag.

Harbor version

v2.15.0

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions