{"id":"02ce7b85b0ecd720","repo":"docker/cli","slug":"duplicate-mount-target","errorCode":null,"errorMessage":"duplicate mount target","messagePattern":"duplicate mount target","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/service/update.go","lineNumber":934,"sourceCode":"\tkeyFunc func(string) string,\n) []string {\n\tnewSeq := []string{}\n\tfor _, item := range seq {\n\t\tif _, exists := toRemove[keyFunc(item)]; !exists {\n\t\t\tnewSeq = append(newSeq, item)\n\t\t}\n\t}\n\treturn newSeq\n}\n\nfunc updateMounts(flags *pflag.FlagSet, mounts *[]mount.Mount) error {\n\tmountsByTarget := map[string]mount.Mount{}\n\n\tif flags.Changed(flagMountAdd) {\n\t\tvalues := flags.Lookup(flagMountAdd).Value.(*opts.MountOpt).Value()\n\t\tfor _, mnt := range values {\n\t\t\tif _, ok := mountsByTarget[mnt.Target]; ok {\n\t\t\t\treturn errors.New(\"duplicate mount target\")\n\t\t\t}\n\t\t\tmountsByTarget[mnt.Target] = mnt\n\t\t}\n\t}\n\n\t// Add old list of mount points minus updated one.\n\tfor _, mnt := range *mounts {\n\t\tif _, ok := mountsByTarget[mnt.Target]; !ok {\n\t\t\tmountsByTarget[mnt.Target] = mnt\n\t\t}\n\t}\n\n\tnewMounts := make([]mount.Mount, 0, len(mountsByTarget))\n\n\ttoRemove := buildToRemoveSet(flags, flagMountRemove)\n\n\tfor _, mnt := range mountsByTarget {\n\t\tif _, exists := toRemove[mnt.Target]; !exists {","sourceCodeStart":916,"sourceCodeEnd":952,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/command/service/update.go#L916-L952","documentation":"Emitted by `docker service update --mount-add`. updateMounts (update.go:927-937) indexes the newly added mounts by their Target path; if two --mount-add flags in the same command declare the same target, the second insert hits the map and the CLI errors, because two mounts cannot occupy one container path. (Adding a mount whose target matches an existing service mount is fine — it replaces it.)","triggerScenarios":"`docker service update --mount-add target=/data,source=v1 --mount-add target=/data,source=v2 svc` — two mount-add values with identical `target=` in one invocation.","commonSituations":"Templated/generated update commands that concatenate mount lists with duplicates; copy-paste of a --mount-add flag without changing the target; scripts merging default and override mounts that both map the same path.","solutions":["Remove or change one of the duplicate `target=` paths so each --mount-add has a unique container path","If the intent is to replace an existing mount, pass a single --mount-add with that target (it supersedes the old one) — no --mount-rm needed","Deduplicate the mount list in the script that generates the command"],"exampleFix":"# before\ndocker service update \\\n  --mount-add type=volume,source=a,target=/data \\\n  --mount-add type=volume,source=b,target=/data web\n\n# after\ndocker service update \\\n  --mount-add type=volume,source=a,target=/data \\\n  --mount-add type=volume,source=b,target=/data-b web","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["swarm","service","update","mounts","validation"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}