Skip to content
Latchkey

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.

docker build output
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 build

Diagnose it: build context, cache, or platform?

A Dockerfile that builds locally and fails in CI usually differs in one of three ways: the build context contains different files, the layer cache is cold or poisoned, or the runner architecture does not match what the base image provides.

Terminal
# what is actually being sent as build context (dockerignore applies)
docker build --no-cache --progress=plain -t probe . 2>&1 | head -40

# what platform are you on, and what does the base image support?
docker version --format '{{.Server.Arch}}'
docker buildx imagetools inspect <base-image> | grep -i platform

# prove it is not a cache artefact
docker build --no-cache .

Common 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.

Terminal
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.

.github/workflows/build.yml
- 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 }

Keep the build context small and deterministic

  • A missing .dockerignore sends node_modules, .git, and build output to the daemon, which is slow and can change layer hashes between environments.
  • A COPY of a path that exists locally but is gitignored will fail in CI, because the runner only has what the checkout produced.
  • Multi-arch builds need buildx and QEMU set up explicitly; a plain docker build on an ARM runner silently produces an ARM image.

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.

Frequently asked questions

What causes Docker BuildKit "failed to fetch oauth token"?
There are 3 common causes: no registry login available to the build, credentials lack scope for the base image repo, and expired short-lived token before the build pulled. 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.
How do I fix Docker BuildKit "failed to fetch oauth token"?
There are 2 fixes depending on which cause you have: log in before building, with read scope for the base and pass credentials to the buildx builder. Work through them in order, since the first is the most common.
What does Docker BuildKit "failed to fetch oauth token" actually mean?
A docker build/buildx build fails at the FROM (or a --from) pull with failed to fetch oauth token: unexpected status: 401 Unauthorized.
How do I stop Docker BuildKit "failed to fetch oauth token" happening again?
Authenticate to every private registry the build pulls from, before building. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card