docker/compose · error
unknown copy direction
Error message
unknown copy direction
What it means
The copy direction is derived from service prefixes: a prefix on Source sets fromService, a prefix on Destination sets toService. If neither argument has a SERVICE: prefix, direction stays 0 and Compose cannot identify any container to talk to, so it fails fast with 'unknown copy direction'. Host-to-host copying is not something compose cp does.
Source
Thrown at pkg/compose/cp.go:74
var direction copyDirection
var serviceName string
var copyFunc func(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error
if srcService != "" {
direction |= fromService
serviceName = srcService
copyFunc = s.copyFromContainer
}
if destService != "" {
direction |= toService
serviceName = destService
copyFunc = s.copyToContainer
}
if direction == acrossServices {
return errors.New("copying between services is not supported")
}
if direction == 0 {
return errors.New("unknown copy direction")
}
containers, err := s.listContainersTargetedForCopy(ctx, projectName, options, direction, serviceName)
if err != nil {
return err
}
g := errgroup.Group{}
for _, cont := range containers {
ctr := cont
g.Go(func() error {
name := getCanonicalContainerName(ctr)
var msg string
if direction == fromService {
msg = fmt.Sprintf("%s:%s to %s", name, srcPath, dstPath)
} else {
msg = fmt.Sprintf("%s to %s:%s", srcPath, name, dstPath)
}View on GitHub (pinned to ddc4b044b6)
Solutions
- Prefix exactly one side with the service name: `docker compose cp ./file.txt web:/app/file.txt`
- If you genuinely want host-to-host copies, use plain `cp`/`rsync` — compose cp always involves containers
- Check shell variables used in the command (e.g. `echo "$svc:/path"`) to ensure the service name is not empty
- Verify the service exists with `docker compose ps` so the prefix matches a running service
Example fix
# before
docker compose cp ./app.conf "${SVC:-}:/etc/app.conf"
# after
SVC=web docker compose cp ./app.conf "${SVC}:/etc/app.conf" Defensive patterns
Strategy: validation
Validate before calling
# ensure at least one side carries a service prefix and the variable is set
: "${SVC:?SVC must be set}"
[ -n "${SVC}" ] && docker compose cp ./file "${SVC}:/path" Prevention
- set -u / :? guards on variables used to build SERVICE:PATH strings
- Always test compose cp invocations with fully expanded arguments first (echo them)
When it happens
Trigger: Running `docker compose cp ./file.txt ./other.txt` or api.Copy with options.Source and options.Destination that both lack the `service:` prefix after splitCpArg.
Common situations: Typos where the colon is dropped (`docker compose cp data.json web:/app` vs `web /app`), shell variable expansion producing an empty service name (`$svc:/path` with svc unset), or misunderstanding compose cp as a generic file-copy tool between host paths.
Related errors
- copying between services is not supported
- source can not be empty
- destination can not be empty
- invalid filter '${filter}'
- --index requires one service to be selected
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/06f2e44ee1342a56.
Report an issue: GitHub.