goharbor/harbor · error
This operation only allowed for admin
Error message
This operation only allowed for admin
What it means
The migrate CLI hard-requires the Harbor username to be exactly 'admin' before doing any work, because the v2->OCI chart migration pushes charts into every project and needs admin rights. Any other --username aborts immediately with this exception, before the CA update, helm login, or any chart processing.
Source
Thrown at tools/migrate_chart/migrate_chart.py:115
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 registry
"""
if username != 'admin':
raise Exception('This operation only allowed for admin')
subprocess.run([CA_UPDATE_CMD])
subprocess.run([HELM_CMD, 'registry', 'login', hostname, '--username', username, '--password', password])
charts = [ChartV2(c) for p in CHART_SOURCE_DIR.iterdir() if p.is_dir() for c in p.iterdir() if c.is_file() and c.name.endswith(".tgz")]
with click.progressbar(charts, label="Migrating chart ...", length=len(charts),
item_show_func=lambda x: "{}/{}:{} total errors: {}".format(x.project, x.name, x.version, len(errs)) if x else '') as bar:
for chart in bar:
try:
if chart.name == "" or chart.version == "" :
print("skip the chart {} has no name or version info".format(chart.filepath))
continue
result = chart.migrate(hostname, username, password)
if result.stderr:
errs.append("chart: {name}:{version} in {project} has err: {err}".format(
name=chart.name,
version=chart.version,
project=chart.project,
err=result.stderr
))View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Run with --username admin (or omit it — it defaults to admin) and the matching admin --password
- If the admin password is unknown, reset it via the Harbor UI or htpasswd tooling first
- Do not use robot accounts — they lack the cross-project push rights this tool needs
Example fix
# before python3 migrate_chart.py --hostname harbor.example.com --username bob --password **** # after python3 migrate_chart.py --hostname harbor.example.com --username admin --password '<admin-password>'
Defensive patterns
Strategy: validation
Validate before calling
if username != 'admin':
raise SystemExit('migration requires the admin account; rerun with --username admin')
# equivalent shell guard before invoking:
# [ "$HARBOR_USER" = 'admin' ] || { echo 'admin only'; exit 1; } Prevention
- Default the username to admin in wrapper scripts instead of inheriting CI credentials
- Reset the admin password before migration day so nobody substitutes another account
- Remember robot accounts cannot run this tool
When it happens
Trigger: Running the tool with --username set to anything other than admin (the default is admin, so only an explicitly passed non-admin value triggers it).
Common situations: Operators passing personal or robot/service account credentials via wrapper scripts; teams whose admin password is rotated and someone substitutes another account.
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
- Artifact already exist in harbor
- File {} not exist
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/4390906d5fefc1ee.
Report an issue: GitHub.