failed to resolve source metadata for docker.io/library/fix9-bld-buildd:latest: pull access denied, repository does not exist or may require authorization
in a multi-stage build, with a name you meant as a stage, means the name in
COPY --from= does not match any AS name in the Dockerfile. The
build then treats it as an image and asks Docker Hub for it. Correct the spelling.
The message ends with a hint: (did you mean fix9-bld-build?). Use the stage
name it suggests, exactly as written after AS.
The error
#3 [internal] load metadata for docker.io/library/fix9-bld-buildd:latest
#3 ERROR: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
------
> [internal] load metadata for docker.io/library/fix9-bld-buildd:latest:
------
Dockerfile:6
--------------------
4 |
5 | FROM alpine:latest
6 | >>> COPY --from=fix9-bld-buildd /src/app.txt /app/app.txt
7 | CMD ["cat", "/app/app.txt"]
8 |
--------------------
ERROR: failed to build: failed to solve: fix9-bld-buildd: failed to resolve source metadata for docker.io/library/fix9-bld-buildd:latest: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed (did you mean fix9-bld-build?)
Why it happens
COPY --from= accepts either the name of an earlier stage or an image reference.
The first stage here was declared AS fix9-bld-build and the copy asked for
fix9-bld-buildd, one extra letter. No stage had that name, so the build expanded
it to docker.io/library/fix9-bld-buildd:latest and tried to load its metadata
from Docker Hub, as step #3 shows. No repository of that name exists, and the answer came
back as "pull access denied ... may require authorization". The wording talks about
authorization, but the cause here was only the spelling.
The failure came before any stage ran: the output has no RUN step at all. The
misspelled name cost one request to Docker Hub. If the typo happens to be the name
of a real public image, the build would copy from that image instead; that case was not
tested here.
The fix
FROM alpine:latest AS fix9-bld-build
WORKDIR /src
RUN echo "built" > /src/app.txt
FROM alpine:latest
COPY --from=fix9-bld-build /src/app.txt /app/app.txt
CMD ["cat", "/app/app.txt"]
With the name matching the AS line, docker build --progress=plain -t fix9-bld-c3 .
ended with exit code: 0, and docker run --rm fix9-bld-c3
printed built. Short stage names such as build and
publish are easy to mistype; copying the name from the AS line
instead of retyping it avoids the extra letter.
How it was reproduced
A two-stage Dockerfile on alpine:latest (image id 294b683cb724) with one
letter added to the stage name in COPY --from, built with
docker build --progress=plain -t fix9-bld-c3 . on Docker Desktop for Windows,
client and engine 29.9.3, buildx v0.38.1. The stage, image and container names carry the
test's own prefix so the misspelled name could not exist on Docker Hub.
Frequently asked
- Why does COPY --from try to pull an image in docker build?
- The name after --from matched no stage in the Dockerfile, so it was treated as an image name and looked up on Docker Hub. Check the spelling against the AS name.
- What does 'did you mean' at the end of a docker build error mean?
- In this test it named the stage whose spelling was closest to the one in COPY --from. Using that name fixed the build.
- Is pull access denied in a multi-stage build a login problem?
- Not in this case. The name was a misspelled stage, so no repository of that name existed on Docker Hub; correcting the spelling fixed the build.
More decoded errors in the Fixes category. The same
message from docker pull or docker run, with a misspelled image
name, is covered in
pull access denied, repository does not exist.