docker/cli · error

source can not be empty

Error message

source can not be empty

What it means

In newCopyCommand RunE (cli/command/container/cp.go:139), after the Args validator (cli.ExactArgs(2)) ensures two args exist, the code explicitly checks args[0] at line 140-141 and returns errors.New("source can not be empty") if the first positional arg is the empty string. An empty source path has no meaning for the copy operation.

Solutions

  1. Provide a non-empty source path or container:path spec: `docker cp ./file web:/tmp`.
  2. Quote-check your shell variables: ensure `$SRC` is set and non-empty before the command (e.g. `${SRC:?source required}`).
  3. If streaming a tar via stdin, use '-' as the source, not the empty string.

Example fix

# before
SRC=""
docker cp "$SRC" web:/tmp
# after
SRC=./file.txt
docker cp "$SRC" web:/tmp
Defensive patterns

Strategy: validation

Validate before calling

// Guard shell variable expansion:
// ${SRC:?source required} aborts if SRC is unset/empty.
// In Go, before building argv:
if source == "" { return errors.New("source can not be empty") }

Try / catch

if err := cmd.Execute(); err != nil {
    if strings.Contains(err.Error(), "source can not be empty") {
        // prompt for source / fix argv
    }
}

Prevention

When it happens

Trigger: Running `docker cp "" dest`, `docker cp "" CONTAINER:/path`, or any invocation where the first positional argument resolves to an empty string (e.g. an unexpanded/empty shell variable like `docker cp "$EMPTY" web:/tmp`).

Common situations: Unset shell variables expanded to empty; quoting bugs; programmatic argv construction leaving args[0] as ""; `docker cp '' web:/x`.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/644e8944f0133c3c. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/container/cp.go:141

// newCopyCommand creates a new `docker cp` command
func newCopyCommand(dockerCLI command.Cli) *cobra.Command {
	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,
	}

View on GitHub (pinned to 4f84911bfe)