GitHub Actions "denied: permission_denied" Pushing to GHCR
A docker push to ghcr.io was denied because the GITHUB_TOKEN lacks packages: write, the login used the wrong credentials, or the package belongs to a different owner than the repo.
What this error means
A docker/login-action plus push to ghcr.io fails with "denied: permission_denied" or an unauthorized error during the push, after a seemingly successful login.
denied: permission_denied: write_package
# or
unauthorized: unauthenticated: User cannot be authenticated with the token provided.Common causes
Missing packages: write
Pushing a container package to GHCR requires the workflow token to have packages: write. A read-only token is rejected.
Wrong login or package ownership
Logging in with the wrong username, or pushing to an image path under a different owner than the repo, fails authorization.
How to fix it
Grant packages: write and log in correctly
permissions:
contents: read
packages: write
steps:
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- run: docker push ghcr.io/${{ github.repository }}:latestMatch the image path and package access
- Push to ghcr.io/<owner>/<name> where the owner matches the repo owner.
- For org packages, ensure the repo has write access to the package.
- Use a PAT with write:packages when pushing across owners the GITHUB_TOKEN cannot reach.
How to prevent it
- Declare packages: write only on jobs that publish images.
- Keep the GHCR image path aligned with the repository owner.
- Grant the publishing repo write access to org-level packages.