Quick Fix: TL;DR
This error usually means Docker BuildKit can't locate a file or directory mentioned in your COPY or ADD instruction. Most fixes involve one of these three checks:
- Build Context: Are you running the
docker buildcommand from the right directory? Usually, this is the project root. - Path Accuracy: Does the source path in your
Dockerfileexist relative to where you launched the build? - .dockerignore: Is the file you're trying to copy accidentally blocked by a
.dockerignorerule?
Why This Happens
BuildKit generates a unique cache key for every layer. When it hits a COPY command, it scans the "build context"βthe directory path you provide at the end of the command (like .). If you tell Docker to COPY config.json . but config.json isn't in that context folder, BuildKit stops immediately with a "not found" error.
failed to solve: rpc error: code = Unknown desc = failed to compute cache key: "/config.json" not found: not found
Common Root Causes
1. Wrong Build Context
Context errors happen most when developers run builds from subdirectories. Imagine a project structured like this:
my-project/
βββ app/
β βββ main.py
β βββ Dockerfile
βββ requirements.txt
If you cd app and then run docker build -t my-app ., Docker only sees files inside the app/ folder. Since requirements.txt is one level up, a COPY requirements.txt . command will fail. Fix this by running the build from the root directory instead:
# Run this from my-project/
docker build -t my-app -f app/Dockerfile .
2. Over-aggressive .dockerignore Rules
The .dockerignore file prevents bulky or sensitive files from reaching the Docker daemon. However, a broad wildcard like *.json or dist/ might block a file you actually need for the image. If a file is ignored, it doesn't exist as far as BuildKit is concerned.
Solution: Review your .dockerignore patterns. If you need to include a specific file that otherwise matches an ignore pattern, use the ! exception prefix:
# Ignore all JSON files...
*.json
# ...except for the one the app needs
!important-config.json
3. Case-Sensitivity Conflicts
Windows and macOS filesystems are generally case-insensitive, but Docker containers run on Linux, which is strictly case-sensitive. A Dockerfile that asks for COPY app.js . will fail if the actual file is named App.js. While it might work on your local machine during development, it will likely break in a CI/CD pipeline running on a Linux runner.
The Fix: Audit your filenames. Ensure the casing in your Dockerfile matches the disk exactly.
4. Leading Slashes in Source Paths
Source paths in COPY or ADD should be relative to the build context. Adding a leading slash changes the search behavior and often leads to errors.
# WRONG: Searches for /src in the system root
COPY /src ./src
# RIGHT: Searches for src within your project folder
COPY src ./src
Debugging Your Context
If you're still stuck, use a "debug" build to see exactly what Docker sees. This takes about 30 seconds and eliminates the guesswork.
- Create a
debug.Dockerfile:
FROM alpine
WORKDIR /check
COPY . .
CMD ls -R
- Run the build and check the output:
docker build -t build-debug -f debug.Dockerfile .
docker run --rm build-debug
If ls -R doesn't show your file, it's either missing from the folder or excluded by .dockerignore.
Best Practices
- Standardize the Root: Launch your builds from the project root to keep paths predictable.
- Limit Context Size: Large context folders (e.g., 500MB+) slow down builds. Use
.dockerignorefornode_modulesand.git. - Use Relative Paths: Avoid absolute paths or leading slashes for source files.
- Match Casing: Stick to lowercase filenames to avoid cross-platform headaches.

