Skip to content
Latchkey

Crossplane "cannot push package" (registry auth) in CI

crossplane xpkg push uploads an .xpkg to an OCI registry like xpkg.upbound.io or GHCR. A push fails when the runner is not logged in, the token lacks write scope, or the repository reference is wrong.

What this error means

A publish step running crossplane xpkg push fails with an "unauthorized" or "denied" error from the registry, or "cannot push package".

crossplane
crossplane: error: failed to push package: PUT https://xpkg.upbound.io/v2/...:
unexpected status code 401 Unauthorized: authentication required

Common causes

The runner is not authenticated to the registry

No docker/registry login ran in CI, so the push is anonymous and the registry returns 401.

The token lacks write access to the repository

Authentication succeeded but the token cannot push to that repository (403/denied), often a read-only or wrong-scope token.

How to fix it

Log in with a scoped token, then push

  1. Log in to the registry using a CI secret with write scope.
  2. Push the built package to the correct repository reference.
  3. Confirm the token can write to that specific repository.
Terminal
echo "${{ secrets.XPKG_TOKEN }}" | crossplane xpkg login \
  --username=robot --password-stdin xpkg.upbound.io
crossplane xpkg push xpkg.upbound.io/org/configuration:v1.0.0 \
  -f configuration.xpkg

Push to a registry you can write to

For GHCR, authenticate with a token that has package write scope and push to the matching path.

Terminal
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
crossplane xpkg push ghcr.io/org/configuration:v1.0.0 -f configuration.xpkg

How to prevent it

  • Store a write-scoped registry token as a CI secret.
  • Log in before every push step.
  • Verify the token has write access to the target repository.

Frequently asked questions

What causes ""cannot push package""?
No docker/registry login ran in CI, so the push is anonymous and the registry returns 401.
How do I fix "cannot push package"?
Log in with a scoped token, then push

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card