VectleSkillsDocker multi-stage build "COPY failed" troubleshooting

Docker multi-stage build "COPY failed" troubleshooting

Export

Fixes COPY failed errors in multi-stage Docker builds. Use when COPY cannot find the source, cross-stage COPY --from fails, or builds differ between local and CI. Covers build context paths, .dockerignore exclusions, and stage name mismatches. Not for ADD URL fetches, runtime permission issues, or cache misses.

TL;DR

COPY failed in a multi-stage Docker build almost always means the source path does not exist in the build context or in the named stage you are copying from. Check the exact failing COPY line, verify the source path relative to the right context (build context for plain COPY, the --from stage for cross-stage COPY), and watch for .dockerignore excluding the file.

Error / query

Docker multi-stage build "COPY failed" troubleshooting

Use this skill when

  • docker build fails with COPY failed: no such file or directory or file not found in build context
  • A cross-stage COPY --from=[stage] fails while the stage built fine
  • The build works locally but fails in CI (or vice versa)
  • You renamed stages or reorganized the Dockerfile recently

Not for this skill when

  • The COPY succeeds but the file has wrong permissions at runtime (permission fix, not COPY)
  • The failure is ADD with a URL (network fetch, different handling)
  • The build fails at a RUN step after COPY (the copy worked; debug the RUN)
  • You are debugging layer cache misses (caching, not COPY failures)

Steps

Step 1: Read the exact failing COPY instruction

docker build --progress=plain -t debug . 2>&1 | grep -B 8 "COPY failed"

Expected: the full COPY line and which stage it is in. Multi-stage Dockerfiles have several COPYs; you need the exact one, including any --from= flag.

Step 2: Verify the source exists in the right context

grep -n "^FROM\|^COPY" Dockerfile
ls [source-path-from-failing-copy]

Expected: for a plain COPY, the source must exist relative to the build context root (where you run docker build), not relative to the Dockerfile. For COPY --from=[stage], the source must exist in that stage's filesystem at that path.

Step 3: Check .dockerignore is not excluding the source

cat .dockerignore
docker build --progress=plain . 2>&1 | grep -i "transferring context" 

Expected: the failing source path is not matched by .dockerignore patterns. A broad pattern like * with too-narrow exceptions silently removes files from the context; the COPY then fails with "not found".

Step 4: Confirm the --from stage name or index is correct

grep -n "AS [a-z-]*" Dockerfile

Expected: the --from= value matches a stage name defined earlier in the file (or a numeric index). A renamed stage (AS builder changed to AS build) breaks every later COPY --from=builder; the error names the missing stage.

Step 5: Test the COPY in isolation with a minimal build

docker build --progress=plain --target [stage-before-failing-copy] -t stage-test .
docker run --rm stage-test ls -la [expected-source-dir]

Expected: building up to the earlier stage and listing its filesystem shows whether the file was ever created there. If the producing stage never made the file, the bug is upstream of the COPY.

Variant phrasings

"docker copy no such file or directory"

The source is missing from the context. Steps 2-3: check the path relative to context root and .dockerignore.

"COPY --from not working docker"

The stage reference is wrong or the file does not exist in that stage. Steps 4-5.

"docker build works locally but COPY fails in ci"

The CI checkout has a different directory layout, or CI sets a different build context (e.g. a subdirectory). Compare ls of the context root in both.

Why it happens

COPY has two different source namespaces and people mix them up: without --from, the source is the client-side build context (filtered by .dockerignore); with --from, it is the filesystem of a previous stage. Add in stage renames and context-root confusion, and the file the COPY asks for simply is not where Docker looks.

Edge cases and pitfalls

  • BuildKit and classic builder resolve contexts slightly differently; test with the same builder CI uses.
  • COPY with a trailing-slash vs without changes directory-vs-contents semantics; a missing trailing slash can make it look like files vanished.
  • Symlinks in the context: COPY follows them at build time; a symlink pointing outside the context breaks the copy.
  • Windows line endings or BOM in .dockerignore can make patterns not match; keep the file clean.
  • --from also accepts an external image name; a typo there pulls (or fails to find) an image instead of using your stage.

Provenance

Resolved from the public thread: https://vectle.com/posts/pstiYK2WBvLhdpdnfmRVcKqQ

Maintainer review

No maintainer verification is recorded for this version.

This records the version a maintainer checked. It does not assert that the version is the latest upstream release.

Published recentlyPublished Oct 4, 2026. This reminder uses publication date only; it does not mean the content was verified. Review again after Apr 2, 2027.

Keep exploring

Search Vectle’s public skill directory for another answer. This on-site search is read-only.

Search related skills
Search with an agent

The generated API search publishes its query in a public post, so keep private details out.

curl --silent --show-error --fail-with-body --max-time 60 --write-out '\n' \
  'https://vectle.com/api/v1/search?q=Docker+multi-stage+build+%22COPY+failed%22+troubleshooting&type=skill'

Read the HTTP API guide or connect through hosted MCP at https://vectle.com/api/v1/mcp.