docker/cli · error
destination " : " must be a directory or a regular file
Error message
destination "%s:%s" must be a directory or a regular file: %w
What it means
Returned during `docker cp` when the destination path inside the container exists and stat-succeeds but its file mode fails command.ValidateOutputPathFileMode (cli/command/container/cp.go:386-388). That validator only accepts directories or regular files; any other mode bit (device, socket, named pipe/FIFO, or a non-regular/symlink-targeted irregular file) is rejected. The destination container and path are included in the message.
Solutions
- Choose a destination path that is a regular file or an existing directory.
- If targeting a directory, ensure it actually is a directory (stat it inside the container: docker exec <c> test -d <path>).
- Avoid copying onto sockets/devices; copy to a normal path and let the application read it.
- Verify the destination is not a symlink to an irregular file.
Example fix
# before docker cp ./file.txt mycontainer:/var/run/docker.sock # socket is not dir/regular # after docker cp ./file.txt mycontainer:/tmp/file.txt
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the container destination is a dir or regular file before copying.
func validateCpDestination(ctx context.Context, c client.APIClient, container, path string) error {
st, err := c.ContainerStatPath(ctx, container, client.ContainerStatPathOptions{Path: path})
if err != nil { return nil } // absent destination is allowed by cp
mode := st.Stat.Mode
if !mode.IsDir() && mode&os.ModeType == 0 { return nil } // regular file
return fmt.Errorf("destination mode (%v) is not a directory or regular file", mode)
} Type guard
// isDirOrRegular reports whether an os.FileMode is a dir or regular file.
func isDirOrRegular(m os.FileMode) bool { return m.IsDir() || m&os.ModeType == 0 } Prevention
- Do not copy onto /dev nodes, sockets, or FIFOs.
- Stat the destination inside the container before scripting docker cp.
When it happens
Trigger: Copying to a container path that resolves to a device node (/dev/*), a unix socket, a named pipe, or any non-regular non-directory file. The check runs after following symlinks on the destination, so a symlink whose target is irregular also triggers it.
Common situations: Destination path is /dev/something or /var/run/docker.sock (a socket); copying into a FIFO used by a service; or a path that became a device via a bind-mount inside the container.
Related errors
- source can not be empty
- destination can not be empty
- must specify at least one container source
- container ID file found, make sure the other container…
- destination " : " must be a directory
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/85121bc2a4d8ab30.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/container/cp.go:387
// Prepare destination copy info by stat-ing the container path.
dstInfo := archive.CopyInfo{Path: dstPath}
if dst, err := apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: dstPath}); err == nil {
// If the destination is a symbolic link, we should evaluate it.
if dst.Stat.Mode&os.ModeSymlink != 0 {
linkTarget := dst.Stat.LinkTarget
if !isAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := archive.SplitPathDirEntry(dstPath)
linkTarget = filepath.Join(dstParent, linkTarget)
}
dstInfo.Path = linkTarget
dst, err = apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: linkTarget})
}
// Validate the destination path
if err == nil {
if err := command.ValidateOutputPathFileMode(dst.Stat.Mode); err != nil {
return fmt.Errorf(`destination "%s:%s" must be a directory or a regular file: %w`, copyConfig.container, dstPath, err)
}
dstInfo.Exists, dstInfo.IsDir = true, dst.Stat.Mode.IsDir()
}
// Ignore any error and assume that the parent directory of the destination
// path exists, in which case the copy may still succeed. If there is any
// type of conflict (e.g., non-directory overwriting an existing directory
// or vice versa) the extraction will fail. If the destination simply did
// not exist, but the parent directory does, the extraction will still
// succeed.
_ = err // Intentionally ignore stat errors (see above)
}
var (
content io.ReadCloser
resolvedDstPath string
copiedSize int64
contentSize int64View on GitHub (pinned to 4f84911bfe)