GHCR "unauthorized: access to the requested resource is not authorized"
GHCR refused a pull because the token used is not authorized to read that package. The image is private and either the token lacks read scope or the package is not linked to a repo the token can see.
What this error means
A docker pull ghcr.io/<org>/<image> fails with unauthorized: access to the requested resource is not authorized. It is deterministic - the same pull fails every run until the package visibility or token access changes.
Error response from daemon: unauthorized: access to the requested resource is
not authorized
# pulling a private ghcr.io/myorg/api with a token that can't read the packageCommon causes
The package is private and the token lacks read access
A private GHCR package requires authentication with read scope. An anonymous pull, or a GITHUB_TOKEN from a repo not linked to the package, is not authorized.
The package is not linked to the repository
GHCR grants the workflow token access based on package↔repo linkage. An unlinked package does not inherit the repo’s permissions, so the default token cannot read it.
Using a token from a different repo/org
A GITHUB_TOKEN or PAT scoped to another repository or organization does not grant access to this package.
How to fix it
Authenticate with a read-scoped token
Log in to GHCR with a token that can read packages before pulling.
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} # or a PAT with read:packagesLink the package to the repo or make it visible
- In the package settings, link it to the repo whose workflow pulls it (grants the repo’s token access).
- Or set the package visibility to internal/public if appropriate.
- Or use a PAT with
read:packagesthat has access to the package.
How to prevent it
- Set
permissions: packages: readon jobs that pull private GHCR images. - Link GHCR packages to the consuming repositories.
- Use least-privilege read-scoped tokens for pull-only jobs.