Helm OCI "failed to authorize" / unauthorized in CI
Helm OCI charts use the registry's auth. A missing helm registry login, an expired token, or a credential without push/pull rights produces "failed to authorize" or "unauthorized" when you push or pull the chart.
What this error means
helm push/pull/install of an oci:// chart fails with "Error: failed to authorize: ... 401 Unauthorized" or "unauthorized: authentication required".
Error: failed to authorize: failed to fetch oauth token: unexpected status from
GET request to https://ghcr.io/token...: 401 UnauthorizedCommon causes
No registry login on the runner
The job pushes or pulls an OCI chart without first running helm registry login, so the request is anonymous and rejected.
Credentials lack push/pull scope
The token authenticates but is not permitted to read or write that package, yielding 401/403 on the operation.
How to fix it
Log in to the registry before push/pull
Authenticate with a token from a secret, then run the OCI operation.
echo "${{ secrets.GHCR_TOKEN }}" | helm registry login ghcr.io \
--username ${{ github.actor }} --password-stdin
helm push my-app-1.4.2.tgz oci://ghcr.io/my-org/chartsGrant the token the right scope
For a persistent 401/403, ensure the credential has package read (pull) or write (push) permission for that registry path.
How to prevent it
- Run
helm registry loginbefore any OCI push/pull in CI. - Store registry tokens as secrets with least-privilege package scope.
- Rotate tokens and update the secret in one place.