docker/cli · error
destination can not be empty
Error message
destination can not be empty
What it means
In newCopyCommand RunE at line 143-144, after confirming args[0] is non-empty, the code checks args[1] and returns errors.New("destination can not be empty") if the second positional arg is the empty string. The copy must have a concrete destination (local path or container:path, or '-' to stream to stdout).
Solutions
- Provide a concrete destination path or container:path, or '-' to stream a tar to stdout.
- Guard your shell variable: `${DEST:?destination required}`.
- Double-check quoting/expansion when building args dynamically.
Example fix
# before DEST="" docker cp web:/tmp/out "$DEST" # after DEST=./out.txt docker cp web:/tmp/out "$DEST" # or stream to stdout docker cp web:/tmp/out -
Defensive patterns
Strategy: validation
Validate before calling
// Guard shell variable expansion:
// ${DEST:?destination required} aborts if DEST is unset/empty.
// In Go:
if dest == "" { return errors.New("destination can not be empty") } Try / catch
if err := cmd.Execute(); err != nil {
if strings.Contains(err.Error(), "destination can not be empty") {
// prompt for destination / fix argv
}
} Prevention
- Quote and check shell variables before `docker cp` (`${DEST:?}`).
- Use '-' explicitly to stream a tar to stdout.
- Validate argv in wrappers before invoking docker.
When it happens
Trigger: Running `docker cp web:/tmp/file ""`, `docker cp ./file ""`, or any invocation where the destination positional argument is an empty string (unset/empty shell variable).
Common situations: Unset destination shell variables; programmatic argv construction leaving args[1] as ""; intending to stream to stdout but forgetting the '-' character.
Related errors
- source can not be empty
- must specify at least one container source
- copying between containers is not supported
- container ID file found, make sure the other container…
- got a device
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/fa15014d010a0590.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/container/cp.go:144
var opts copyOptions
cmd := &cobra.Command{
Use: `cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH`,
Short: "Copy files/folders between a container and the local filesystem",
Long: `Copy files/folders between a container and the local filesystem
Use '-' as the source to read a tar archive from stdin
and extract it to a directory destination in a container.
Use '-' as the destination to stream a tar archive of a
container source to stdout.`,
Args: cli.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
if args[0] == "" {
return errors.New("source can not be empty")
}
if args[1] == "" {
return errors.New("destination can not be empty")
}
opts.source = args[0]
opts.destination = args[1]
if !cmd.Flag("quiet").Changed {
// User did not specify "quiet" flag; suppress output if no terminal is attached
opts.quiet = !dockerCLI.Out().IsTerminal()
}
return runCopy(cmd.Context(), dockerCLI, opts)
},
Annotations: map[string]string{
"aliases": "docker container cp, docker cp",
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symlinks in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")View on GitHub (pinned to 4f84911bfe)