Why your docker login ghcr.io keeps failing and why AI gets it wrong
Every few weeks, I see the same advice floating around, from AI assistants, Stack Overflow snippets, or auto-generated DevOps docs:
Just log in with your GitHub Personal Access Token (PAT):
echo $TOKEN | docker login ghcr.io -u USERNAME --password-stdin
Looks fine, right? Except it usually doesn't work.
When you try to pull or push an image from GitHub's Container Registry (GHCR), you might run into mysterious authentication errors. The reason isn't Docker, nor GitHub's fault, it's the missing scope.
The Problem
Most generic AI answers and many tutorials forget that GitHub's Personal Access Tokens (PATs) are scoped.
By default, a token with only repo permissions won't be able to interact with packages, including your container images.
That means this will fail silently or return a 401 Unauthorized when you try:
docker pull ghcr.io/hemp0r/those-containerz:latest
AI models tend to memorize documentation patterns, not permission hierarchies. The official GitHub Docs mention scopes, but examples are simplified for readability. So AI often parrots the snippet, not the nuance. And in security-sensitive systems like container registries, that missing nuance breaks automation.
The Real Fix
You need to manually create a Personal Access Token (classic) or a fine-grained token that explicitly includes:
read:packages→ required for pulling imageswrite:packages→ required for pushing images
Then, log in like this:
echo $GITHUB_TOKEN | docker login ghcr.io -u your-github-username --password-stdin
Now it works. Simple, explicit, and CI/CD-friendly.
Best Practice for CI/CD
In GitHub Actions or other CI/CD systems:
Create a dedicated automation token (not your personal one).
Grant only
read:packagesorwrite:packagesdepending on what you need.Store it securely as a secret (e.g.,
GHCR_TOKEN).Use it during your workflow:
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u your-username --password-stdin
This avoids permission errors, keeps your pipeline clean, and doesn't rely on undocumented defaults.
Final Thought
When AI says, “Just use your GitHub token,” always ask: which scopes? Because DevOps isn't magic, it's access control with better UX.