goharbor/harbor · warning
Artifact already exist in harbor
Error message
Artifact already exist in harbor
What it means
Raised by ChartV2.migrate when the Harbor v2.0 existence check GET /api/v2.0/projects/{project}/repositories/{name}/artifacts/{version} returns 200 — the chart already exists at the destination and the tool refuses to overwrite it. The exception propagates to the CLI loop, gets appended to the errs list, and the batch continues with the next chart.
Source
Thrown at tools/migrate_chart/migrate_chart.py:94
self.name, self.version = read_chart_version(filepath)
if self.name == "" or self.version == "" or self.name is None or self.version is None :
raise Exception('chart name: {} is illegal'.format('-'.join(parts)))
except Exception as e:
click.echo("Skipped chart: {} due to illegal chart name. Error: {}".format(filepath, e), err=True)
return
def __check_exist(self, hostname, username, password):
return requests.get(CHART_URL_PATTERN.format(
host=hostname,
project=self.project,
name=self.name,
version=self.version),
auth=requests.auth.HTTPBasicAuth(username, password))
def migrate(self, hostname, username, password):
res = self.__check_exist(hostname, username, password)
if res.status_code == 200:
raise Exception("Artifact already exist in harbor")
if res.status_code == 401:
raise Exception(res.reason)
oci_ref = "oci://{host}/{project}".format(
host=hostname,
project=self.project)
return subprocess.run([MIGRATE_CHART_SCRIPT, HELM_CMD, self.filepath, oci_ref],
text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
@click.command()
@click.option('--hostname', default='127.0.0.1', help='the password to login harbor')
@click.option('--username', default='admin', help='The username to login harbor')
@click.option('--password', default='Harbor12345', help='the password to login harbor')
def migrate(hostname, username, password):
"""
Migrate chart v2 to harbor oci registryView on GitHub (pinned to 7b2fd08cc5)
Solutions
- Treat it as expected on re-runs — the artifact is already migrated; filter these out of errs when reviewing results
- Delete the existing artifact first (DELETE /api/v2.0/projects/{project}/repositories/{name}/artifacts/{version}) and re-run
- Bump the chart version in Chart.yaml and repackage if a fresh copy is actually needed
- Patch migrate() to log-and-skip on status 200 instead of raising
Example fix
# before
if res.status_code == 200:
raise Exception("Artifact already exist in harbor")
# after
if res.status_code == 200:
click.echo("Already migrated: {}/{}:{}".format(self.project, self.name, self.version), err=True)
return subprocess.CompletedProcess(args=[], returncode=0) Defensive patterns
Strategy: try-catch
Try / catch
try:
result = chart.migrate(hostname, username, password)
except Exception as e:
if 'already exist' in str(e):
# idempotent re-run: already migrated, not an actual failure
continue
errs.append(str(e)) Prevention
- Track migrated charts externally so re-runs skip them at the source
- Review migration_errors.txt knowing 'already exist' entries are informational
- Delete artifacts you genuinely want re-pushed before re-running the tool
When it happens
Trigger: Re-running the migration tool after a previous complete or partial run; a chart whose name+version was already pushed to Harbor by CI, a manual helm push, or an earlier migration attempt.
Common situations: Idempotent re-runs after interruption, retrying a failed batch, dev/staging chart sources sharing one Harbor instance.
Related errors
- Failed to read chart.yaml from the chart tgz file. filename
- chart.yaml not found in the chart tgz file. filename {}
- chart name: {} is illegal
- This operation only allowed for admin
- File {} not exist
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/94ec6df21247ec78.
Report an issue: GitHub.