{"record":{"id":"b243466156935b68","repo":"docker/cli","slug":"copying-between-containers-is-not-supported","errorCode":null,"errorMessage":"copying between containers is not supported","messagePattern":"copying between containers is not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/container/cp.go","lineNumber":243,"sourceCode":"\t}\n\n\tvar direction copyDirection\n\tif srcContainer != \"\" {\n\t\tdirection |= fromContainer\n\t\tcopyConfig.container = srcContainer\n\t}\n\tif destContainer != \"\" {\n\t\tdirection |= toContainer\n\t\tcopyConfig.container = destContainer\n\t}\n\n\tswitch direction {\n\tcase fromContainer:\n\t\treturn copyFromContainer(ctx, dockerCli, copyConfig)\n\tcase toContainer:\n\t\treturn copyToContainer(ctx, dockerCli, copyConfig)\n\tcase acrossContainers:\n\t\treturn errors.New(\"copying between containers is not supported\")\n\tdefault:\n\t\treturn errors.New(\"must specify at least one container source\")\n\t}\n}\n\nfunc resolveLocalPath(localPath string) (absPath string, _ error) {\n\tabsPath, err := filepath.Abs(localPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn archive.PreserveTrailingDotOrSeparator(absPath, localPath), nil\n}\n\nfunc copyFromContainer(ctx context.Context, dockerCLI command.Cli, copyConfig cpConfig) (err error) {\n\tdstPath := copyConfig.destPath\n\tsrcPath := copyConfig.sourcePath\n\n\tif dstPath != \"-\" {","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/cp.go#L225-L261","documentation":"runCopy (cli/command/container/cp.go:215) splits source and destination into container+path via splitCpArg and ORs their directions. If both source and destination contain a container specifier (direction == acrossContainers, i.e. fromContainer|toContainer), line 242-243 returns errors.New(\"copying between containers is not supported\"). The `docker cp` operation always involves the local filesystem as one endpoint; container-to-container copy requires two hops.","triggerScenarios":"Running `docker cp web1:/path web2:/path` or `docker cp ctrA:/a ctrB:/b` — both arguments are parsed as CONTAINER:PATH because both contain a ':' with a non-relative prefix.","commonSituations":"Users expecting scp-like host-to-host semantics; copy-pasting container IDs into both sides; misreading docs.","solutions":["Copy in two steps via the local filesystem: `docker cp web1:/path ./tmp && docker cp ./tmp web2:/path`.","Or use a tar pipe: `docker cp web1:/path - | docker cp - web2:/path`.","Use `docker exec` with tar/cp inside a shared volume if both containers share a volume mount.","Remember `docker cp` always has the local FS as one endpoint."],"exampleFix":"# before (unsupported)\ndocker cp web1:/app/out web2:/app/in\n# after — two hops through the local filesystem\ndocker cp web1:/app/out ./out && docker cp ./out web2:/app/in","handlingStrategy":"validation","validationCode":"// Detect container specifiers on both sides before calling runCopy:\nsrcCtr, _ := splitCpArg(src)\ndstCtr, _ := splitCpArg(dst)\nif srcCtr != \"\" && dstCtr != \"\" {\n    return errors.New(\"copying between containers is not supported; copy via the local filesystem\")\n}","typeGuard":"// splitCpArg returns a non-empty container token when the arg is CONTAINER:PATH.\nfunc isContainerSpec(arg string) bool { ctr, _ := splitCpArg(arg); return ctr != \"\" }","tryCatchPattern":"if err := runCopy(ctx, cli, opts); err != nil {\n    if strings.Contains(err.Error(), \"copying between containers is not supported\") {\n        // fall back to a two-hop copy through the local FS\n    }\n    return err\n}","preventionTips":["Remember `docker cp` always has the local filesystem as one endpoint.","For container-to-container, pipe through a tar: `docker cp a:/x - | docker cp - b:/x`.","Use a shared volume for frequent cross-container file exchange."],"tags":["container","cp","unsupported","filesystem"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}