How to fix COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such file or directory in Docker

DockerINTERMEDIATEMEDIUMUpdated Dec 6, 2025ยท 255 views

This error occurs during Docker multi-stage builds when COPY --from cannot find the specified file or directory in the source stage. The fix involves verifying paths are correct, using absolute paths, and ensuring files are created in the expected locations during the build stage.

Quick fix

Fixes COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such file or directory

FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Debug: List what was created
RUN ls -la /app/dist/
  1. Verify the file exists in the build stage
  2. Use absolute paths in COPY --from commands
  3. Check the stage name matches exactly
  4. Account for WORKDIR in both stages
docker โ€” error
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Debug: List what was created
RUN ls -la /app/dist/
COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such file or directory

What this error means

The "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such file or directory" error occurs when Docker cannot locate a file or directory you're trying to copy, particularly during multi-stage builds with `COPY --from`. In multi-stage builds, you compile or build artifacts in one stage (e.g., a "builder" stage) and then copy only the necessary files to a smaller production image. This error indicates that the path specified in your COPY command doesn't exist in the source stage's filesystem. The overlay2 path in the error message is Docker's internal storage driver path and isn't something you interact with directly. The important part is "no such file or directory" which tells you Docker can't find what you're trying to copy.

Typical symptoms

  • Docker build fails with 'COPY failed: stat ... no such file or directory'
  • Multi-stage builds fail at the COPY --from step
  • Error message contains /var/lib/docker/overlay2/ paths
  • Build succeeds locally but fails in CI/CD pipelines
  • Error occurs only with certain base images or Docker versions
  • Build worked previously but fails after Dockerfile changes

Common causes

  1. Using relative paths instead of absolute paths in COPY --from commands
  2. File or directory wasn't created in the build stage (e.g., build command failed silently)
  3. Wrong stage name or index in --from flag
  4. WORKDIR differences between stages causing path mismatches
  5. Environment variables used in paths (they don't expand in COPY)
  6. Build artifact location changed but Dockerfile wasn't updated
  7. Using CMD instead of RUN for build commands (CMD doesn't execute during build)
  8. Files excluded by .dockerignore in earlier COPY commands

How to fix "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such file or directory"

1Verify the file exists in the build stage

Add a RUN ls command in your build stage to confirm the file is being created where you expect:

dockerfile
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Debug: List what was created
RUN ls -la /app/dist/

If the ls command fails or shows no files, your build step isn't creating the expected output. Check your build command's output for errors.

2Use absolute paths in COPY --from commands

Always use absolute paths when copying from another stage. WORKDIR from the source stage doesn't apply to your COPY command:

Wrong (relative path):

dockerfile
FROM node:18 AS builder
WORKDIR /app
RUN npm run build
# Creates files in /app/dist/

FROM nginx:alpine
# This fails - looks for ./dist in nginx image context
COPY --from=builder dist/ /usr/share/nginx/html/

Correct (absolute path):

dockerfile
FROM node:18 AS builder
WORKDIR /app
RUN npm run build

FROM nginx:alpine
# Use absolute path from builder stage
COPY --from=builder /app/dist/ /usr/share/nginx/html/

The key insight: COPY --from=builder dist/ looks for dist/ in the current stage's context, not the builder's WORKDIR.

3Check the stage name matches exactly

Ensure the stage name in --from= matches your AS declaration exactly (case-sensitive):

dockerfile
# Stage named "builder" (lowercase)
FROM golang:1.21 AS builder
RUN go build -o /app/myservice

FROM alpine:3.18
# Must match exactly - "builder" not "Builder" or "build"
COPY --from=builder /app/myservice /usr/local/bin/

You can also use numeric indexes (0-based):

dockerfile
FROM golang:1.21
RUN go build -o /app/myservice

FROM alpine:3.18
# --from=0 refers to the first stage
COPY --from=0 /app/myservice /usr/local/bin/

Named stages are clearer and less error-prone than numeric indexes.

4Account for WORKDIR in both stages

Understand how WORKDIR affects file locations:

dockerfile
FROM node:18 AS builder
# WORKDIR sets current directory to /app
WORKDIR /app
COPY . .
# npm run build creates files in /app/dist (relative to WORKDIR)
RUN npm run build

FROM node:18-slim
WORKDIR /app
# Source path is absolute from builder stage
# Destination path is relative to this stage's WORKDIR
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./

Key points:
- The source path (after --from=builder) should be absolute
- The destination path is relative to the current stage's WORKDIR
- Each stage has its own independent WORKDIR

5Don't use environment variables in COPY paths

Environment variables are NOT expanded in COPY commands:

This won't work:

dockerfile
FROM golang:1.21 AS builder
ENV APP_DIR=/app
WORKDIR $APP_DIR
RUN go build -o $APP_DIR/myservice

FROM alpine:3.18
# $APP_DIR won't expand here!
COPY --from=builder $APP_DIR/myservice /usr/local/bin/

Use hardcoded paths instead:

dockerfile
FROM golang:1.21 AS builder
WORKDIR /app
RUN go build -o /app/myservice

FROM alpine:3.18
COPY --from=builder /app/myservice /usr/local/bin/

If you need dynamic paths, use ARG with default values:

dockerfile
ARG BUILD_DIR=/app
FROM golang:1.21 AS builder
WORKDIR /app
RUN go build -o /app/myservice

FROM alpine:3.18
COPY --from=builder /app/myservice /usr/local/bin/
6Use RUN instead of CMD for build commands

A common mistake is using CMD instead of RUN for build steps. CMD only runs when the container starts, not during the build:

Wrong - CMD doesn't execute during build:

dockerfile
FROM node:18 AS builder
WORKDIR /app
COPY . .
# CMD doesn't run during 'docker build'!
CMD ["npm", "run", "build"]

FROM nginx:alpine
# This fails - /app/dist was never created
COPY --from=builder /app/dist/ /usr/share/nginx/html/

Correct - RUN executes during build:

dockerfile
FROM node:18 AS builder
WORKDIR /app
COPY . .
# RUN executes during 'docker build'
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist/ /usr/share/nginx/html/

Remember:
- RUN: Executes during image build
- CMD: Executes when container starts
- ENTRYPOINT: Configures container as executable

7Check .dockerignore for excluded files

Your .dockerignore might exclude files needed for the build:

bash
# View your .dockerignore
cat .dockerignore

Common problematic patterns:

bash
# This excludes source files needed for build!
src/
*.ts

# This excludes config files
*.json

A better approach - exclude only what you don't need:

bash
# .dockerignore
node_modules
.git
.gitignore
*.md
Dockerfile
.dockerignore
.env*
coverage/
.nyc_output/

If unsure, temporarily rename .dockerignore and rebuild to see if that's the issue:

bash
mv .dockerignore .dockerignore.bak
docker build -t test .
mv .dockerignore.bak .dockerignore
8Clean Docker build cache if issues persist

Sometimes cached layers cause stale state. Clean the build cache:

bash
# Remove build cache
docker builder prune

# Build without using cache
docker build --no-cache -t myimage .

# For Docker Compose
docker compose build --no-cache

In severe cases, a more thorough cleanup:

bash
# Remove all unused images, containers, and cache
docker system prune -a

# Then rebuild
docker build -t myimage .

Note: docker system prune -a removes all unused images, not just dangling ones. Use with caution in shared environments.

Advanced notes

Understanding Docker's overlay2 storage driver: The overlay2 filesystem is Docker's default storage driver on Linux. Each layer of an image is stored in /var/lib/docker/overlay2/. The "merged" directory is a union mount of all layers. When you see overlay2 paths in error messages, Docker is telling you where it looked for the file in its internal storage.

Cross-compilation considerations: When building for different platforms (e.g., compiling Go for Linux on macOS), ensure your binary is built for the correct target:

dockerfile
FROM golang:1.21 AS builder
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
RUN go build -o /app/myservice

BuildKit and cache mounts: With BuildKit, you can use cache mounts to speed up builds while avoiding some COPY issues:

dockerfile
# syntax=docker/dockerfile:1
FROM node:18 AS builder
WORKDIR /app
RUN --mount=type=cache,target=/root/.npm \
    npm ci

Debugging with intermediate containers: You can run a shell in the build stage to investigate:

bash
# Build up to the builder stage
docker build --target builder -t debug-builder .

# Explore the filesystem
docker run -it --rm debug-builder sh
ls -la /app/

COPY vs ADD behavior: Both COPY and ADD can fail with this error. Key differences:
- COPY: Simple file/directory copy
- ADD: Can extract archives and fetch URLs (but avoid for simple copies)

Use COPY unless you specifically need ADD's extra features.

Symlinks and COPY: COPY follows symlinks and copies the target content. If your build creates symlinks, the actual files must exist:

dockerfile
# If build creates a symlink dist -> dist-v1.2.3
# COPY will try to copy dist-v1.2.3's contents
COPY --from=builder /app/dist/ /usr/share/nginx/html/

Frequently asked questions

What does "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such fil" mean?
: no such file or directory" error occurs when Docker cannot locate a file or directory you're trying to copy, particularly during multi-stage builds with COPY --from. , a "builder" stage) and then copy only the necessary files to a smaller production image. This error indicates that the path specified in your COPY command doesn't exist in the source stage's filesystem.
How do I fix "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such fil"?
This error occurs during Docker multi-stage builds when COPY --from cannot find the specified file or directory in the source stage. The fix involves verifying paths are correct, using absolute paths, and ensuring files are created in the expected locations during the build stage.
What causes "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such fil"?
Using relative paths instead of absolute paths in COPY --from commands File or directory wasn't created in the build stage (e.g., build command failed silently) Wrong stage name or index in --from flag
Is the "COPY failed: stat /var/lib/docker/overlay2/.../merged/...: no such fil" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading