ARTIFACTORY: How to Create a Legacy Helm Smart Remote Repository

AuthorFullName__c
Ramyashree V, Jeremy Leopold
articleNumber
000006133
FirstPublishedDate
2024-07-02T07:18:58Z
lastModifiedDate
2025-05-23

ARTIFACTORY: How to Create a Legacy Helm Smart Remote Repository

We have a body of documentation on how to set up Helm repositories here, as well as how to set up smart remote repositories here. However, setting up a legacy Helm smart remote repository requires some knowledge of advanced features and Helm-specific quirks.

In this guide, we’ll go over an example where one Artifactory instance uses a legacy Helm smart remote repository to pull artifacts from an upstream legacy Helm local or remote Artifactory repository.
 

Step 1: Setting up the smart remote repository

On an upstream Artifactory, I have a local repository called “helm-local-upstream”, and it contains a single chart. I’d like to set up a smart remote repository that connects with this local repository.

User-added image


Let’s start with creating a remote repository that will point to this upstream local repository. I’ve created a default legacy Helm remote repository, except the URL is in the format of <artifactory_url>/artifactory/api/helm/<target-repository-name>. I’ve also entered my credentials for the upstream Artifactory instance:

User-added image 


You can test the connection with the upstream repository by clicking the “Test” button in the UI: 

User-added image 

If the connection is successful, you should see this message appear:
User-added image

If the connection is unsuccessful, please ensure the credentials are valid and the URL format is correct.

After verifying the connection, let’s head over to the “Advanced” tab. Here, we will need to select “Enable Dependency Rewrite”. You can read more about this feature below. 

User-added image 

After this has been selected, save the repository settings.

 

Step 2: Setting up the virtual repository

As mentioned in our documentation, in order for Artifactory to properly cache Helm charts, we’ll need to resolve them through a virtual repository. So let’s create a virtual legacy Helm repository. I’ve decided to name this one “helm-legacy-virtual”. Within it, I’ve added the “helm-legacy-smart-remote” repository we created above:

User-added image

After adding this, save the repository configuration.
 

Step 3: Resolving a chart from the smart remote

After creating these repositories, let’s set up the Helm client to interact with the virtual repository. You can use the handy “Set Me Up” instructions in the UI:

User-added image

User-added image  


After the repository has been added, run a “helm repo update” for the virtual repository that was just added:

helm repo update helm-legacy-virtual                                                                                          
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "helm-legacy-virtual" chart repository
Update Complete. ⎈Happy Helming!⎈


After performing this update, you should see the upstream local repository’s artifacts in the UI:

User-added image

If we look at the index.yaml for “helm-legacy-virtual”, we will see the URL of this Artifactory as opposed to the URL of the upstream Artifactory. This is due to selecting “Enable Dependency Rewrite” in Step 1. If the URL in the index.yaml still matches the upstream artifactory’s URL, try performing “Zap Caches” on the virtual repository, followed by a “helm repo update”. You can read more about zapping caches here.

User-added image

At this point, you can try pulling a helm chart from the virtual repository. In this example, the upstream has only one chart, postgresql, which I’ll pull here:

helm pull helm-legacy-virtual/postgresql

After pulling this chart, you should also notice that this chart appears in the smart remote’s cache:

User-added image


Understanding Enable Dependency Rewrite and URL Matching
What Enable Dependency Rewrite does: When the downstream Smart Remote fetches the index.yaml from the upstream, the chart download URLs in that index point to the upstream Artifactory. Enable Dependency Rewrite causes the downstream to replace the upstream's base URL in those chart entries with the downstream's own base URL before serving the index to Helm clients. This ensures helm pull requests are routed through the downstream rather than sent directly to the upstream.

Without this rewrite, a Helm client connected to the downstream would receive chart URLs pointing to the upstream. In an air-gapped or DMZ environment where the client cannot reach the upstream, this results in connection failures or 401/403 errors.

The rewrite depends on an exact URL match. The downstream compares each chart URL in the upstream's index.yaml against the Smart Remote's configured URL. If the base matches, the URL is rewritten. If it does not match — even if the difference is only a port number — the URL is passed through unchanged, and the Helm client is directed to the upstream.

Important: Smart Remote URL Must Exactly Match the Upstream's Index URLs

A common cause of mismatch is a reverse proxy (Apache or Nginx) in front of the upstream Artifactory. The proxy sets the X-JFrog-Override-Base-Url header, which the upstream uses when generating chart URLs in its index.yaml. Many default configurations explicitly include :443 in this header:
# Apache
RequestHeader set X-JFrog-Override-Base-Url https://upstream.example.com:443

# Nginx
proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port;
This causes the upstream's index.yaml to contain chart URLs like:
urls:
  - https://upstream.example.com:443/artifactory/api/helm/my-helm-virtual/argo-cd-9.4.14/argo-cd-9.4.14.tgz
If the downstream Smart Remote URL is configured without :443:
https://upstream.example.com/artifactory/api/helm/my-helm-virtual
These are semantically identical but not identical as strings. The dependency rewrite silently fails, and the downstream's virtual index.yaml will contain the upstream's raw URLs instead of the downstream's.

To resolve this, confirm your upstream reverse proxy configuration and add the explicit :443 port to the Smart Remote URL on the downstream so it matches exactly:
https://upstream.example.com:443/artifactory/api/helm/my-helm-virtual

The
helm repo add URL Must Also Match


The same :443 that appears in the upstream's index will also appear in the downstream's rewritten index.yaml if the downstream's own reverse proxy includes :443 in X-JFrog-Override-Base-Url. For example, after a successful rewrite the downstream's virtual index.yaml may contain:
urls:
  - https://downstream.example.com:443/artifactory/api/helm/my-helm-virtual/argo-cd-9.4.14/argo-cd-9.4.14.tgz
Helm matches stored repository credentials against the download URL's host and port. If the repository was added without :443:
helm repo add my-repo https://downstream.example.com/artifactory/api/helm/my-helm-virtual --username ...
Helm will not attach credentials to download URLs that include :443, resulting in 403 Forbidden on chart pulls. To avoid this, include :443 in the helm repo add URL so it matches the chart URLs in the index:
helm repo add my-repo https://downstream.example.com:443/artifactory/api/helm/my-helm-virtual --username ...

Verification
After configuring the Smart Remote URL and performing helm repo update, inspect the downstream virtual's index.yaml to confirm the URLs have been rewritten:
curl -u admin:<password> https://<downstream>:443/artifactory/api/helm/<virtual-repo>/index.yaml | grep "urls:" -A 1
The chart URLs should point to the downstream (https://downstream.example.com:443/...), not the upstream. If they still point to the upstream, the Smart Remote URL does not match the upstream's index URLs — check for port mismatches.