{"record":{"id":"85121bc2a4d8ab30","repo":"docker/cli","slug":"destination-s-s-must-be-a-directory-or-a-regul","errorCode":null,"errorMessage":"destination \"%s:%s\" must be a directory or a regular file: %w","messagePattern":"destination \"(.+?):(.+?)\" must be a directory or a regular file: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/container/cp.go","lineNumber":387,"sourceCode":"\t// Prepare destination copy info by stat-ing the container path.\n\tdstInfo := archive.CopyInfo{Path: dstPath}\n\tif dst, err := apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: dstPath}); err == nil {\n\t\t// If the destination is a symbolic link, we should evaluate it.\n\t\tif dst.Stat.Mode&os.ModeSymlink != 0 {\n\t\t\tlinkTarget := dst.Stat.LinkTarget\n\t\t\tif !isAbs(linkTarget) {\n\t\t\t\t// Join with the parent directory.\n\t\t\t\tdstParent, _ := archive.SplitPathDirEntry(dstPath)\n\t\t\t\tlinkTarget = filepath.Join(dstParent, linkTarget)\n\t\t\t}\n\n\t\t\tdstInfo.Path = linkTarget\n\t\t\tdst, err = apiClient.ContainerStatPath(ctx, copyConfig.container, client.ContainerStatPathOptions{Path: linkTarget})\n\t\t}\n\t\t// Validate the destination path\n\t\tif err == nil {\n\t\t\tif err := command.ValidateOutputPathFileMode(dst.Stat.Mode); err != nil {\n\t\t\t\treturn fmt.Errorf(`destination \"%s:%s\" must be a directory or a regular file: %w`, copyConfig.container, dstPath, err)\n\t\t\t}\n\t\t\tdstInfo.Exists, dstInfo.IsDir = true, dst.Stat.Mode.IsDir()\n\t\t}\n\n\t\t// Ignore any error and assume that the parent directory of the destination\n\t\t// path exists, in which case the copy may still succeed. If there is any\n\t\t// type of conflict (e.g., non-directory overwriting an existing directory\n\t\t// or vice versa) the extraction will fail. If the destination simply did\n\t\t// not exist, but the parent directory does, the extraction will still\n\t\t// succeed.\n\t\t_ = err // Intentionally ignore stat errors (see above)\n\t}\n\n\tvar (\n\t\tcontent         io.ReadCloser\n\t\tresolvedDstPath string\n\t\tcopiedSize      int64\n\t\tcontentSize     int64","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/cp.go#L369-L405","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ndocker cp ./file.txt mycontainer:/var/run/docker.sock   # socket is not dir/regular\n# after\ndocker cp ./file.txt mycontainer:/tmp/file.txt","handlingStrategy":"validation","validationCode":"// Confirm the container destination is a dir or regular file before copying.\nfunc validateCpDestination(ctx context.Context, c client.APIClient, container, path string) error {\n    st, err := c.ContainerStatPath(ctx, container, client.ContainerStatPathOptions{Path: path})\n    if err != nil { return nil } // absent destination is allowed by cp\n    mode := st.Stat.Mode\n    if !mode.IsDir() && mode&os.ModeType == 0 { return nil } // regular file\n    return fmt.Errorf(\"destination mode (%v) is not a directory or regular file\", mode)\n}","typeGuard":"// isDirOrRegular reports whether an os.FileMode is a dir or regular file.\nfunc isDirOrRegular(m os.FileMode) bool { return m.IsDir() || m&os.ModeType == 0 }","tryCatchPattern":null,"preventionTips":["Do not copy onto /dev nodes, sockets, or FIFOs.","Stat the destination inside the container before scripting docker cp."],"tags":["container","copy","filesystem","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}