> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/artifact-registry/use-artifact-registry/artifact-registry-cli/artifact-migration.md).

# Migrate artifacts to Harness Artifact Registry

This guide walks you through migrating artifacts to Harness Artifact Registry from other artifact registries and servers using the Harness CLI.

***

### Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

Make sure you have the following:

* **Harness CLI installed:** Install the [Harness CLI v1 (hc)](https://developer.harness.io/artifact-registry/use-artifact-registry/artifact-registry-cli/spaces/3F2TpHXhur2QtQnORSM9/pages/diDjM2ZlsZHi35szVh4u#v1.0.0-hc--installation) and authenticate to your Harness account. Use the latest version.
* **Source registry access:** Valid credentials (username and API token) for your source artifact registry (for example, Nexus).
* **Destination registries created:** Create the target registries in Harness Artifact Registry before migration. Go to [Artifact Registry best practices](/artifact-registry/troubleshooting-and-resources/ar-best-practices.md) to review guidance on registry setup and configuration.
* **Permissions:** Permissions to create and manage artifact registries in your Harness account. Go to [RBAC in Harness](/harness-ai/use-harness-platform/platform-access-control.md) to configure access control.

***

### Step 1: Create target registries in Harness <a href="#step-1-create-target-registries-in-harness" id="step-1-create-target-registries-in-harness"></a>

Before migrating, create the destination registries in Harness Artifact Registry:

1. Navigate to **Artifact Registry** in your Harness project.
2. Select **New Registry** for each registry you want to migrate to.
3. Configure the registry type, name, and settings.
4. Note the registry identifier for use in the migration configuration.

***

### Step 2: Prepare the migration configuration file <a href="#step-2-prepare-the-migration-configuration-file" id="step-2-prepare-the-migration-configuration-file"></a>

#### Supported artifact types <a href="#supported-artifact-types" id="supported-artifact-types"></a>

The migration tool supports the following artifact types:

| Artifact type | Description                                                                        |
| ------------- | ---------------------------------------------------------------------------------- |
| `DOCKER`      | Docker container images                                                            |
| `HELM`        | OCI-compliant Helm charts                                                          |
| `HELM_LEGACY` | Non-OCI compliant Helm registries (automatically migrated to OCI-compliant format) |
| `GENERIC`     | Generic artifacts and files                                                        |
| `PYTHON`      | Python packages (PyPI)                                                             |
| `MAVEN`       | Maven artifacts                                                                    |
| `NPM`         | NPM packages                                                                       |
| `NUGET`       | NuGet packages                                                                     |
| `RPM`         | RPM packages                                                                       |
| `GO`          | Go modules                                                                         |
| `CONDA`       | Conda packages                                                                     |
| `COMPOSER`    | Composer (PHP) packages                                                            |
| `SWIFT`       | Swift packages                                                                     |
| `TERRAFORM`   | Terraform modules and providers                                                    |
| `CRAN`        | R packages (CRAN format)                                                           |
| `RUBY`        | RubyGems packages                                                                  |
| `ALPINE`      | Alpine Package Keeper (APK)                                                        |
| `WOLFI`       | Wolfi Linux packages (APK)                                                         |

#### Configuration structure <a href="#configuration-structure" id="configuration-structure"></a>

Create a YAML configuration file (for example, `migration-config.yaml`) that defines your migration settings.

{% hint style="info" %}
**IMPORTANT CONFIGURATION REQUIREMENTS**

* Both source and destination endpoints **must use HTTPS** (`https://`).
* The destination endpoint must always be `https://pkg.harness.io`.
* Use **API tokens** (not passwords) for authentication credentials.
  {% endhint %}

The following example shows the configuration structure:

```yaml
version: 1.0.0
concurrency: 5  # Number of packages migrated concurrently.
overwrite: false  # Set to true to overwrite existing artifacts

source:
  endpoint: https://nexus.example.com  # Source registry endpoint (must use https://)
  type: NEXUS  # Source registry type (e.g., NEXUS)
  credentials:
    username: your-username
    password: your-api-token  # Use API token, not password. Can also use env var: ${SOURCE_PASSWORD}
  insecure: false  # Set to true to skip SSL verification (not recommended)

destination:
  endpoint: https://pkg.harness.io  # Harness Artifact Registry endpoint
  type: HAR
  credentials:
    username: your-harness-username
    password: your-harness-token  # Generate from Harness. Can also use env var: ${HARNESS_TOKEN}

mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-local  # Source registry name
    destinationRegistry: harness-docker-reg  # Destination registry identifier in Harness
  - artifactType: HELM
    sourceRegistry: helm-local
    destinationRegistry: harness-helm-reg
    # highlight-next-line
    sourcePackageHostname: https://registry.example.com  # Optional: override source hostname for Docker and Helm artifacts
  - artifactType: MAVEN
    sourceRegistry: maven-releases
    destinationRegistry: harness-maven-reg
```

#### Configuration parameters <a href="#configuration-parameters" id="configuration-parameters"></a>

**Source configuration**

The source block configures the connection to your existing registry:

* **endpoint:** Full HTTPS URL of your source registry.
* **type:** Source registry type (for example, `NEXUS`, `JFROG`).
* **credentials.username:** Username for source registry authentication.
* **credentials.password:** API token for source registry (**important**: use API token, not user password). You can reference environment variables using `${VARIABLE_NAME}` syntax (for example, `${SOURCE_PASSWORD}`).
* **insecure:** Set to `true` to skip SSL certificate verification (use with caution).

**Destination configuration**

The destination block points to Harness Artifact Registry:

* **endpoint:** Always `https://pkg.harness.io` for Harness Artifact Registry.
* **type:** Always `HAR` for Harness.
* **credentials.username:** Your Harness username.
* **credentials.password:** Harness authentication token. You can reference environment variables using `${VARIABLE_NAME}` syntax (for example, `${HARNESS_TOKEN}`).

**Mappings**

Each mapping defines how artifacts are migrated from source to destination:

* **artifactType:** Type of artifact (see supported types table above).
* **sourceRegistry:** Repository name or ID in your source registry.
* **destinationRegistry:** Registry identifier in Harness (must be created beforehand).
* **sourcePackageHostname** (optional): Override the source hostname for Docker and Helm artifacts.

#### Configuration best practices <a href="#configuration-best-practices" id="configuration-best-practices"></a>

1. **Use environment variables** for sensitive credentials:

   ```yaml
   source:
     credentials:
       username: ${SRC_USER}
       password: ${SRC_TOKEN}
   destination:
     credentials:
       username: ${HARNESS_USER}
       password: ${HARNESS_TOKEN}
   ```
2. **Use API tokens**, not passwords, for authentication.
3. **Always use HTTPS** (`https://`) for both source and destination endpoints.
4. **Start with low concurrency** (1-2) for initial testing, then increase for production migrations.
5. **Test with a small registry** before migrating large repositories.

***

### Step 3: Run the migration <a href="#step-3-run-the-migration" id="step-3-run-the-migration"></a>

Execute the migration using the Harness CLI:

```bash
hc registry migrate --config migration-config.yaml --verbose
```

#### Available flags <a href="#available-flags" id="available-flags"></a>

| Flag            | Description                                                                             | Default       |
| --------------- | --------------------------------------------------------------------------------------- | ------------- |
| `-c, --config`  | Path to configuration file                                                              | `config.yaml` |
| `--concurrency` | Number of concurrent operations (overrides config)                                      | `1`           |
| `--dry-run`     | Run migration in dry-run mode (no uploads, generates file list and directory structure) | `false`       |
| `--overwrite`   | Allow overwriting existing artifacts                                                    | `false`       |
| `--pkg-url`     | Base URL for the package API (overrides config)                                         | -             |
| `-v, --verbose` | Enable verbose logging                                                                  | `false`       |

#### Example commands <a href="#example-commands" id="example-commands"></a>

Basic migration:

```bash
hc registry migrate --config migration-config.yaml
```

Migration with custom concurrency:

```bash
hc registry migrate --config migration-config.yaml --concurrency 10
```

Migration with overwrite enabled:

```bash
hc registry migrate --config migration-config.yaml --overwrite
```

Migration with verbose logging:

```bash
hc registry migrate --config migration-config.yaml --verbose
```

Dry-run migration (preview without uploading):

```bash
hc registry migrate --config migration-config.yaml --dry-run
```

This generates a file list and directory structure of what would be migrated without performing any uploads. Use this to verify your configuration before running the actual migration.

***

### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

<details>

<summary>Authentication errors during artifact migration to Harness Artifact Registry</summary>

Verify you are using API tokens (not passwords) and that credentials have appropriate permissions to access both source and destination registries.

</details>

<details>

<summary>Connection failures when migrating artifacts with the Harness CLI</summary>

Ensure the source endpoint URL is correct, uses HTTPS, and is accessible from your network. If using a self-signed certificate, set insecure: true in the configuration (not recommended for production).

</details>

<details>

<summary>Missing artifacts after migration to Harness Artifact Registry</summary>

Run the migration with --verbose to check logs for errors. Verify that all destination registries exist before starting migration and that the artifact type mappings are correct.

</details>

For additional help, run `hc registry migrate --help` or contact Harness Support.

***

### Next steps <a href="#next-steps" id="next-steps"></a>

After successful migration:

* Update your CI/CD pipelines to use Harness Artifact Registry. Go to [Artifact Registry and CD](/artifact-registry/use-artifact-registry/platform-integrations/cd-ar-integrations.md) to configure pipeline integrations.
* Go to [Configure registries](/artifact-registry/use-artifact-registry/manage-registries/configure-registry.md) to set up upstream proxies if needed.
* Go to [Webhooks](/artifact-registry/use-artifact-registry/manage-registries/ar-webhooks.md) to configure automation for your registries.
