docker/compose · error
destination can not be empty
Error message
destination can not be empty
What it means
The counterpart of the source check: docker compose cp validates in PreRunE that args[1] — the destination, either DEST_PATH, '-', or SERVICE:DEST_PATH — is not the empty string. With cli.ExactArgs(2) already guaranteeing two positional args, this catches a present-but-empty second argument (quoted empty string) before runCopy executes.
Source
Thrown at cmd/compose/cp.go:56
followLink bool
copyUIDGID bool
}
func copyCommand(p *ProjectOptions, dockerCli command.Cli, backendOptions *BackendOptions) *cobra.Command {
opts := copyOptions{
ProjectOptions: p,
}
copyCmd := &cobra.Command{
Use: `cp [OPTIONS] SERVICE:SRC_PATH DEST_PATH|-
docker compose cp [OPTIONS] SRC_PATH|- SERVICE:DEST_PATH`,
Short: "Copy files/folders between a service container and the local filesystem",
Args: cli.ExactArgs(2),
PreRunE: Adapt(func(ctx context.Context, 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")
}
return nil
}),
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.source = args[0]
opts.destination = args[1]
return runCopy(ctx, dockerCli, backendOptions, opts)
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := copyCmd.Flags()
flags.IntVar(&opts.index, "index", 0, "Index of the container if service has multiple replicas")
flags.BoolVar(&opts.all, "all", false, "Include containers created by the run command")
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
return copyCmdView on GitHub (pinned to ddc4b044b6)
Solutions
- Set the destination explicitly to a concrete path or '-', verifying the variable first: `: "${DEST:?destination required}"`.
- When piping to stdout, pass '-' as the destination instead of an empty string.
- Audit the surrounding script for misspelled or unexported variables feeding the cp command.
Example fix
# before
docker compose cp web:/app/log.txt "$DEST"
# DEST unset -> empty-string arg
# after
: "${DEST:?destination required}"
docker compose cp web:/app/log.txt "$DEST" Defensive patterns
Strategy: validation
Validate before calling
: "${DEST:?docker compose cp needs a non-empty destination}"
docker compose cp "$SRC" "$DEST" Prevention
- Default destinations explicitly in scripts: DEST="${DEST:-./out.bin}".
- Export CI variables or they expand empty when quoted.
When it happens
Trigger: Running `docker compose cp web:/app/log.txt ""`, or scripts where the destination variable is unset/empty but quoted so the shell still passes an empty argument, e.g. `docker compose cp src "$DEST"` with DEST unset.
Common situations: CI variables not exported into the job environment; typos in variable names (e.g. $DESTNATION); build scripts assuming a default output path that was never set.
Related errors
- source can not be empty
- invalid filter '${filter}'
- --index requires one service to be selected
- arguments to --filter should be in form KEY=VAL
- cannot combine --attach and --attach-dependencies
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/ba1c756414ee414f.
Report an issue: GitHub.