Docker BuildKit "failed to fetch oauth token" - Fix Auth During Build Pull
During the build, BuildKit tried to pull a base image from a private registry and the registry’s token exchange failed. The build cannot authenticate to fetch the FROM image.
What this error means
A docker build/buildx build fails at the FROM (or a --from) pull with failed to fetch oauth token: unexpected status: 401 Unauthorized. It is deterministic until credentials are provided to the builder.
ERROR: failed to solve: failed to fetch oauth token: unexpected status: 401 Unauthorized
# pulling FROM ghcr.io/myorg/base:1.0 without registry auth available to the buildCommon causes
No registry login available to the build
The base image is private but the builder has no credentials - docker login was not run, or buildx runs in a context that does not see the login.
Credentials lack scope for the base image repo
A token that cannot read the base image’s repository fails the OAuth token exchange even though login "succeeded".
Expired short-lived token before the build pulled
A cloud-registry token (ECR, OIDC-minted) expired between login and the build’s pull of the base image.
How to fix it
Log in before building, with read scope for the base
Authenticate to the base image’s registry right before the build.
echo "$TOKEN" | docker login ghcr.io -u "$USER" --password-stdin
docker buildx build -t myorg/api:1.4.2 .Pass credentials to the buildx builder
In Actions, log in before the build-push step so the builder inherits the auth.
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with: { context: ., push: true }How to prevent it
- Authenticate to every private registry the build pulls from, before building.
- Use read-scoped credentials that cover the base image repository.
- Refresh short-lived tokens in the same job that builds.