KhueApps
Home/DevOps/Fixing 'failed to compute cache key: not found' in Docker builds

Fixing 'failed to compute cache key: not found' in Docker builds

Last updated: October 06, 2025

Overview

The Docker/BuildKit error "failed to compute cache key: not found" usually means a COPY/ADD source path is missing from the build context. Common reasons include a too-aggressive .dockerignore, wrong build context directory, typos or case mismatches, or multi-stage COPY --from references that don’t exist.

This guide shows fast checks, a minimal repro, fixes, pitfalls, and performance tips.

Quickstart

  1. Verify the build context
  • Run the build from the project root that contains the files you COPY.
  • Ensure you didn’t use stdin builds that strip context (e.g., docker build - < Dockerfile).
  1. Check .dockerignore
  • Remove patterns that exclude required sources, or re-include with !pattern.
  1. Confirm paths and case
  • Paths in COPY are relative to the build context. Case is significant inside images, even on Windows hosts.
  1. Validate multi-stage names
  • Ensure COPY --from uses an existing stage name or index, and the path exists in that stage.
  1. Get verbose output
  • Use: docker build --progress=plain --no-cache .

Minimal working example (repro and fix)

The following intentionally fails, then shows the fix.

Failing setup

# Create a demo project
mkdir demo && cd demo

# Dockerfile that copies package manifests, then the app
cat > Dockerfile <<'EOF'
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]
EOF

# .dockerignore that wrongly excludes required files
cat > .dockerignore <<'EOF'
node_modules
.git
# Oops: these exclusions cause the error below
package.json
package-lock.json
EOF

# Minimal app files
cat > package.json <<'EOF'
{
  "name": "cachekey-demo",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": { "start": "node server.js" }
}
EOF

echo 'console.log("ok")' > server.js

# Build (will fail):
DOCKER_BUILDKIT=1 docker build -t cachekey-demo --progress=plain .

You’ll see an error for the COPY step similar to:

  • failed to compute cache key: "package.json": not found

Fix

# Keep useful ignores but allow required files into the context
cat > .dockerignore <<'EOF'
node_modules
.git
EOF

# Rebuild (should succeed)
docker build -t cachekey-demo --progress=plain .

Step-by-step diagnosis

  1. Confirm the context directory
  • The last argument to docker build is the context. Example: docker build -f Dockerfile .
  • If you pass -, you’re likely sending only the Dockerfile via stdin, yielding an empty context. Use a real directory as context.
  1. Inspect .dockerignore
  • Look for patterns that exclude needed files (e.g., src/, package*.json, dist/).
  • Use ! to re-include files if you exclude a directory:
    • Example: exclude dist but keep dist/index.html by adding !dist/index.html.
  1. Verify file existence and case
  • Ensure the source exists relative to the context, not relative to WORKDIR.
  • Confirm case-sensitive matches: README.md is not README.MD inside the image.
  1. Check COPY source forms
  • COPY fileA fileB ./ fails if either source doesn’t exist.
  • Wildcards must match at least one file; otherwise, COPY fails.
  1. Multi-stage builds
  • Ensure the stage name matches exactly:
    • FROM node:20-alpine AS build
    • COPY --from=build /app/dist/ /usr/share/nginx/html/
  • Verify the path exists in the source stage (e.g., /app/dist/ was created).
  1. Symlinks and outside-context paths
  • Docker won’t copy files outside the build context. Symlinks pointing outside are excluded.
  1. Git build contexts
  • If building from a remote Git URL, ensure submodules and the needed files are present. Vendor or include them explicitly.
  1. Re-run with plain progress
  • docker build --progress=plain --no-cache . provides clearer step logs.

Common causes and fixes

CauseSymptomFix
.dockerignore excludes sourceCOPY fails with not foundRemove or adjust pattern; use ! to re-include required files
Wrong build contextFiles present locally but missing in buildRun docker build from project root; pass the correct context path
Typo or case mismatchPath looks correct on Windows but fails in imageMatch exact case; verify relative paths to context
COPY multiple sources, one missingGeneric not found errorEnsure every source exists; avoid over-broad wildcards
Multi-stage alias mismatchCOPY --from=builder but stage is buildRename to match or update --from
Artifact missing in stageCOPY --from path doesn’t existConfirm build step creates the artifact and path
Symlink points outside contextNot found or silently excludedKeep files inside context; resolve symlinks beforehand
Stdin build (no context)Any COPY of local files failsProvide a directory context; avoid docker build - < Dockerfile

Pitfalls

  • Using COPY package*.json ./ when only package.json exists is fine if it matches at least one file; if it matches none, the build fails.
  • Excluding entire directories (e.g., src/) in .dockerignore while trying to COPY them later.
  • Building from a subfolder that omits needed top-level files.
  • Forgetting to rename COPY --from after refactoring stage names.
  • Relying on host case-insensitivity; container filesystems are case-sensitive.

Performance notes

  • Keep context small but correct: Use .dockerignore to exclude large, unneeded paths (node_modules, .git, logs). Re-include only the files you need.
  • Order Dockerfile steps to maximize cache:
    • COPY only dependency manifests first (e.g., package.json) and run installs before copying the rest of the source.
  • Use BuildKit cache mounts for package managers to speed repeated builds:
    • RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
  • Avoid invalidating cache by changing many files before early layers. Keep frequent edits in later COPY steps.
  • For multi-stage builds, copy only final artifacts (e.g., dist/) into the runtime image.

Tiny FAQ

Q: Why does this mention cache if the file is missing? A: BuildKit computes cache keys per step using inputs. If a source is missing or excluded, the solver can’t resolve the key and fails with not found.

Q: How do I see what files are in the context? A: There’s no direct listing, but you can tar and inspect: tar -czf - . --exclude-from=.dockerignore | tar -tz to approximate what’s sent.

Q: Does ADD behave differently from COPY? A: Both fail if sources are missing. ADD can fetch URLs and auto-extract archives, but won’t bypass .dockerignore or outside-context rules.

Q: Why does it work with DOCKER_BUILDKIT=0? A: Classic builder sometimes emits different messages, but the underlying issue (missing or excluded files) remains. Fix the context or paths.

Series: Docker

DevOps