Docker "cannot copy to non-directory" - Fix COPY Destination Errors
A COPY/ADD tried to place files inside a destination that already exists as a regular file, not a directory. Docker cannot treat a file as a folder, so it refuses.
What this error means
The build fails on a COPY step with cannot copy to non-directory. The source files are fine; the problem is that the destination path was created as a file by an earlier instruction.
ERROR: failed to solve: cannot copy to non-directory:
/usr/src/app/config
# an earlier COPY created "config" as a file, now another COPY treats it as a dirCommon causes
The destination already exists as a file
An earlier COPY src config made config a file; a later COPY a b config/ then tries to copy into it as a directory. The two uses of the same path conflict.
Copying multiple sources without a trailing slash
When a COPY has more than one source, the destination must be a directory and end with /. Without the slash Docker may interpret the target as a single file, clashing with the multiple sources.
A WORKDIR or earlier ADD shadowed the path
A path that was a directory in one stage can be a file in another, so a copy that worked earlier breaks after a refactor of the Dockerfile layout.
How to fix it
Make the destination an explicit directory
End the destination in a slash and ensure nothing earlier created it as a file.
# multiple sources need a directory destination:
COPY package.json package-lock.json ./
# or copy into a clearly-directory path:
COPY config/ /usr/src/app/config/Audit earlier instructions touching the same path
Grep the Dockerfile for the conflicting path and reconcile whether it is a file or a directory.
grep -nE 'config' Dockerfile
# rename one usage so a file and a directory don't collideHow to prevent it
- Always end directory destinations with
/, especially for multi-source COPY. - Keep a single, consistent meaning (file vs directory) for each destination path.
- Review COPY destinations after refactoring stage layouts.