docker failed to compute cache key: failed to calculate checksum of ref - not found (the 6 causes, tested on Docker 28)
TL;DR
- "failed to compute cache key ... not found" is COPY telling you the source path is not in the build context. It happens before any layer is built, which is why
--no-cachechanges nothing. - The context is the last argument of
docker build, not the folder with the Dockerfile.cd docker && docker build .sends only thedocker/folder;docker build -f docker/Dockerfile .from the project root is the fix. - The six causes I reproduced: a typo in the file name, the wrong context directory, a
.dockerignorerule, wrong letter case (App.pyvsapp.py), a multi-stageCOPY --frompath that does not exist in that stage, and the same mistakes on the legacy builder, which words it asCOPY failed: file not found in build context or excluded by .dockerignore. - See what BuildKit really received: a two-line throwaway Dockerfile with
COPY . /ctxandRUN find /ctx -type flists the context. - Every output below is from Docker 28.0.4 with BuildKit (buildx 0.38) on Ubuntu 24.04, captured on 2026-10-15.
I first wrote this post after hitting the error on my Windows laptop in 2021: my Dockerfile lived in a sub-folder and I ran docker build from inside it. That is still the most common cause. But when I reproduced it properly on Docker 28 for this rewrite, I found five more ways to get the identical message, and one case where BuildKit quietly does something you did not ask for. All six are below with their real output.
Table of Content
- What the error means
- Cause 1: the file name is wrong
- Cause 2: you built from the wrong directory
- Cause 3: dockerignore excluded the file
- Cause 4: letter case
- Cause 5: multi-stage COPY --from path
- Cause 6: the legacy builder, and why --no-cache does not help
- Two commands that show what the context contains
- What broke when I ran this
- Conclusion
1. What the error means
| Cause | Error text (Docker 28.0.4) | Fix |
|---|---|---|
| typo in COPY source | "/main.py": not found | match the name in the context |
| wrong context dir | "/app.py": not found from cd docker && docker build . | docker build -f docker/Dockerfile . from the root |
.dockerignore | "/app.py": not found while the file is on disk | fix the pattern, or add !app.py |
| letter case | "/App.py": not found | Linux paths are case-sensitive, even when your Mac or Windows is not |
| multi-stage path | "/src/dist": not found on COPY --from=build | use the path the earlier stage really produced |
| legacy builder | COPY failed: file not found in build context or excluded by .dockerignore | same fixes; the text is just older |
BuildKit computes a checksum of every COPY and ADD source before it runs anything, so it can decide whether a cached layer can be reused. That is the "cache key". A source that does not exist in the context has no checksum, so the build stops at that line with not found. The Dockerfile COPY reference states the rule in one sentence: the source path is relative to the build context.
2. Cause 1: the file name is wrong
My project has app.py and requirements.txt. The Dockerfile asks for main.py:
1FROM python:3.12-alpine
2WORKDIR /app
3COPY requirements.txt .
4COPY main.py .
5CMD ["python","main.py"]
1$ docker build -q -t ck:1 .
2Dockerfile:4
3--------------------
4 2 | WORKDIR /app
5 3 | COPY requirements.txt .
6 4 | >>> COPY main.py .
7 5 | CMD ["python","main.py"]
8--------------------
9ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::u1tatgayj8t94v575ydb9luf2: "/main.py": not found
BuildKit points at the exact line (>>> COPY main.py .) and names the missing path at the end. The long ref identifier in the middle is the context snapshot; ignore it, the useful part is always the quoted path after it.
3. Cause 2: you built from the wrong directory
This was my original 2021 mistake. The Dockerfile sits in docker/, so I changed into that folder and built:
1$ cd docker && docker build -q -t ck:2 .
2Dockerfile:3
3--------------------
4 1 | FROM python:3.12-alpine
5 2 | WORKDIR /app
6 3 | >>> COPY app.py .
7--------------------
8ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::q6kp0t1cxlus5luq9sfah8abl: "/app.py": not found
app.py exists, one level up. But the context is ., which is now docker/, and app.py is not in it. Keep the context at the project root and point -f at the Dockerfile:
1$ docker build -q -t ck:2 -f docker/Dockerfile .
2sha256:9365c8363f0184f75d5ad8ee5736c90dad8bbecea6b7329d5a8c100ab62a2e6e
Docker's build context documentation is explicit: the context and the Dockerfile location are two independent things.
4. Cause 3: dockerignore excluded the file
The file is on disk, the context is right, and the build still fails:
1$ docker build -q -t ck:3 .
2ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::3ta980nno2bjqfdzxajl1lskj: "/app.py": not found
3
4$ cat .dockerignore
5*.py
.dockerignore is applied when the context is sent, so an excluded file is simply absent as far as BuildKit is concerned. A negation line keeps the file you need:
1$ printf '*.py\n!app.py\n' > .dockerignore
2$ docker build -q -t ck:3 .
3sha256:9365c8363f0184f75d5ad8ee5736c90dad8bbecea6b7329d5a8c100ab62a2e6e
The same image ID as the successful build in cause 2, because the context content is now identical. Patterns like *, **/node_modules or .git in a copied-in .dockerignore are a classic way to lose a file you need; the syntax is documented on the dockerignore page.
5. Cause 4: letter case
On macOS and Windows, App.py and app.py are the same file. Inside the build they are not:
1$ docker build -q -t ck:4 .
2 3 | >>> COPY App.py .
3ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::om2yunn1mi7kovnp8jd6v7rrg: "/App.py": not found
The context is a Linux filesystem on the builder, and the file is app.py. Match the case exactly.
6. Cause 5: multi-stage COPY --from path
In a multi-stage build the "context" for COPY --from=build is the filesystem of that stage, and the error wording is identical:
1FROM node:22-alpine AS build
2WORKDIR /src
3RUN mkdir -p build && echo "<h1>hi</h1>" > build/index.html
4FROM nginx:1.27-alpine
5COPY --from=build /src/dist /usr/share/nginx/html
1$ docker build -q -t ck:6 .
2 5 | >>> COPY --from=build /src/dist /usr/share/nginx/html
3ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::ud8d6fq2vdjaarxf0ti4ebmnm: "/src/dist": not found
The first stage wrote to build/, the second asked for dist/. This one bites when you change a framework's output folder (Vite uses dist, Create React App used build) and forget the Dockerfile. With the path corrected, the build passes:
1$ docker build -q -t ck:6 .
2sha256:1db0cfb3c8988f70bbd8aebef733324d5c57d88a864afb0a703d9582eb50a0a2
7. Cause 6: the legacy builder, and why --no-cache does not help
With DOCKER_BUILDKIT=0 the same typo produces the older message many forum answers quote:
1$ DOCKER_BUILDKIT=0 docker build -q -t ck:8 .
2DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
3Sending build context to Docker daemon 7.168kB
4Step 3/3 : COPY main.py .
5COPY failed: file not found in build context or excluded by .dockerignore: stat main.py: file does not exist
That wording is more helpful - it even mentions .dockerignore - but it is the same problem. And because the failure happens while BuildKit is computing the cache key, clearing the cache cannot fix it:
1$ docker build --no-cache -q -t ck:8 .
2ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 6134b6ae-8eb1-4f62-889e-a360c80bcfbf::ickrbqd70hholx8h76pmkklya: "/main.py": not found
If you reached for --no-cache or docker builder prune, stop: the word "cache" in the message is misleading. The file is missing.
8. Two commands that show what the context contains
When none of the causes above is obvious, list the context exactly as BuildKit sees it. This throwaway Dockerfile copies everything and prints it:
1$ printf "FROM alpine:3.20\nCOPY . /ctx\nRUN find /ctx -type f | sort\n" > Dockerfile.ctx
2$ docker build --no-cache --progress=plain -f Dockerfile.ctx . 2>&1 | grep -E "^#[0-9]+ [0-9.]+ /ctx"
3#7 0.141 /ctx/Dockerfile
4#7 0.141 /ctx/Dockerfile.ctx
5#7 0.141 /ctx/app.py
6#7 0.141 /ctx/docker/Dockerfile
7#7 0.141 /ctx/requirements.txt
8#7 0.141 /ctx/static/a.txt
If the file you are copying is not in that list, the cause is the context directory or .dockerignore. If it is in the list, the cause is the spelling or case in your COPY line. The whole context here was 7.168 kB, and BuildKit reported the Dockerfile load DONE at 0.0 s, the context transfer DONE at 0.0 s, the base image DONE at 0.5 s and the find output at 0.141 s, so this check costs nothing; on a project with a node_modules folder, add that folder to .dockerignore first or the listing will be enormous.
9. What broke when I ran this
All of this ran as a script on a fresh GitHub Actions runner (Ubuntu 24.04, Docker 28.0.4) on 2026-10-15. Two results were not what I expected.
1. COPY ../requirements.txt . did not fail. I added it as "cause 5: copying from outside the context", expecting a forbidden path outside the build context error. Instead the build succeeded. BuildKit normalises the source path against the context root, so ../requirements.txt became /requirements.txt, which exists in my context. The copy "worked" only because a file with that name happened to be at the root; if it had not, the error would have been the usual not found. The lesson is that .. never reaches outside the context, and it never errors either, so a parent-directory path in a COPY line is always a bug waiting to be noticed.
2. COPY static/* /app/static/ and COPY static /app/static2 produced the same result. I expected the glob form to flatten or fail; both copied a.txt into the target directory. The difference only appears when static contains sub-directories, where the glob copies their contents but not the directories themselves. Not an error, but worth knowing when a sub-folder "disappears" after a copy.
10. Conclusion
failed to compute cache key ... not found is a missing file in the build context. To summarise:
- Read the quoted path at the end of the error; BuildKit names exactly what it could not find.
- Check the context: it is the last argument of
docker build, minus.dockerignore. Build from the project root with-fpointing at the Dockerfile. - Check spelling and letter case, and in multi-stage builds check the path the earlier stage really produced.
- Do not clear the cache; the problem is not cached.
If the file copies but the container then cannot find it at runtime, Docker COPY vs ADD explains the destination side, and if the error is about a source with no matching files at all, see COPY failed: no source files were specified. For the image tag errors that often follow a fixed build, see docker: invalid reference format.
Did this save you a debugging session? Stay in the loop -
- Subscribe on YouTube - every post here has a screen-recorded companion video.
- Code on GitHub - the repositories, Terraform and scripts behind these posts.
Posts in this series
- (docker run -d) Why Does a Docker Container Stop Automatically?
- Detach from a Docker container without stopping it - docker attach, Ctrl-P Ctrl-Q, --sig-proxy and --detach-keys (tested on Docker 28)
- docker rename image - How to Rename a Docker Image or Change Its Repository Name (docker tag + docker rmi, with Real Output)
- How to set-up Cron Jobs in Docker Containers?
- Docker Copy File from Host to Container - docker cp, Bind Mounts, Docker Compose and Dockerfile COPY (Complete Guide)
- Docker Compose command with multiple commands and multiple lines - sh -c, the list form, $$ and depends_on (tested on Compose v2.38)
- How to push Docker Images to AWS ECR(Elastic Container registry)?
- How to Copy Docker images from one host to another host?
- What is persistent storage in docker and how to manage it
- Docker Installation on MacOS, Linux and Windows
- Docker - ADD, Update, Export Environment variable
- docker failed to compute cache key: failed to calculate checksum of ref - not found (the 6 causes, tested on Docker 28)
- Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint - Bind for 0.0.0.0:8080 failed: port is already allocated (Fix in One Minute)
- exec - executable file not found in $PATH (or %PATH%) in Docker - every cause and fix, inside the container and on the host
- How to expose port on live containers?
- How to expose multiple ports with Docker?
- docker restart container - Restart One Container (or One Compose Service) Without Touching the Others, with Real Output from Docker 28
- How to edit file within Docker container or edit a file after I shell into a Docker container?
- Failed to start docker.service: Unit docker.service not found - the fix on CentOS, Rocky and RHEL 9 (and why dnf install docker makes it worse)
- How to remove old, unused images of Docker?
- docker: invalid reference format - Every Cause Reproduced with Docker 28 (repository name must be lowercase, spaces in -v, empty variables, wrong argument order) and the Fix for Each
- How to fix requested access to the resource is denied?
- docker rmi conflict - unable to remove repository reference, container is using its referenced image (every docker rm and rmi conflict fixed, with real output)
- How to fix docker error no space left on device?
- How to connect localhost from docker container?
- Docker COPY vs Docker ADD?
- 6 Ways to fix - Got permission denied while trying to connect to the Docker daemon socket?
- 6 Ways to fix – Docker COPY failed: stat no source files were specified