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

  1. Run with --username admin (or omit it — it defaults to admin) and the matching admin --password
  2. If the admin password is unknown, reset it via the Harbor UI or htpasswd tooling first
  3. 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

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


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/4390906d5fefc1ee. Report an issue: GitHub.