> 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/3.0/use-artifact-registry/artifact-registry-cli/artifact-migration.md).

# Migrate Artifacts to Harness Artifact Registry

Learn how to migrate artifacts to Harness Artifact Registry using the Harness CLI.

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)](/harness-platform/3.0/harness-platform-resources/automation/cli/install.md#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/3.0/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-platform/3.0/harness-platform-resources/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/3.0/use-artifact-registry/platform-integrations/cd-ar-integrations.md) to configure pipeline integrations.
* Go to [Configure registries](/artifact-registry/3.0/use-artifact-registry/manage-registries/configure-registry.md) to set up upstream proxies if needed.
* Go to [Webhooks](/artifact-registry/3.0/use-artifact-registry/manage-registries/ar-webhooks.md) to configure automation for your registries.

{% @harness-feedback/feedback %}
