Skip to content

ArgoCD and private Helm repositories

In a real enterprise, charts don’t live on a public GitHub repo — they’re in Artifactory, Nexus, or a cloud registry, behind credentials. Getting ArgoCD to authenticate there is where people lose an afternoon, mostly because there are two different kinds of Helm repository and they’re configured differently.

Watch on YouTube ↗
  • A classic (HTTP) Helm repository serves an index.yaml listing charts over HTTP(S). This is Artifactory’s helm repository type, ChartMuseum, GitHub Pages, and so on.
  • An OCI registry stores charts as OCI artifacts alongside container images (oci://…). This is the newer, increasingly default approach — the same registry that holds your images can hold your charts.

ArgoCD supports both, but you register them differently, and this is the crux of most “it can’t find my chart” confusion.

ArgoCD reads repository credentials from labelled secrets in its namespace. For a classic HTTP Helm repo:

apiVersion: v1
kind: Secret
metadata:
name: artifactory-helm
namespace: openshift-gitops
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: helm
name: artifactory
url: https://artifactory.example.com/artifactory/api/helm/helm-local
username: <user>
password: <api-token>

The argocd.argoproj.io/secret-type: repository label is what makes ArgoCD pick the secret up. Your Application’s repoURL then matches this url.

For OCI it’s the same secret shape with two differences — type stays helm, but you set enableOCI and use an oci://-style host:

stringData:
type: helm
name: artifactory-oci
url: artifactory.example.com # host only, no scheme
username: <user>
password: <api-token>
enableOCI: "true"

And the Application references it with an OCI URL and a chart name rather than a path:

spec:
source:
repoURL: artifactory.example.com/helm-oci
chart: demo
targetRevision: 1.2.3

The other credential path: pulling images vs pulling charts

Section titled “The other credential path: pulling images vs pulling charts”

Worth separating clearly, because they’re often the same registry but two different mechanisms:

  • ArgoCD pulling the chart uses the repository secret above.
  • The cluster pulling the container images the chart references uses a standard Kubernetes imagePullSecret in the destination namespace (or attached to the service account). ArgoCD authenticating to the chart repo does nothing for image pulls.

So a chart can sync perfectly and the pods still fail with ImagePullBackOff — because that’s a second credential, on the cluster side, that also needs setting up. If you helm registry login locally to test, note that’s yet another context (your Docker/Helm config), separate from both of the above. Three places, one registry — keep them straight and the confusion disappears.