{"record":{"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/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/service/update.go#L916-L952","documentation":"Thrown by updateMounts (cli/command/service/update.go:934) while indexing newly-added mounts by their Target path. If two `--mount-add` flags specify the same container destination, the second collides in the mountsByTarget map and the error fires, since a container cannot have two mounts bound to one path.","triggerScenarios":"Passing multiple `--mount-add` with an identical `target=`/`dst=`, e.g. `docker service update --mount-add type=bind,src=/a,target=/data --mount-add type=volume,src=vol,target=/data <svc>`.","commonSituations":"Copy-pasting a mount flag and editing only the source while leaving the target; templating that renders the same target twice; refactoring a volume list and forgetting to dedupe destinations.","solutions":["Give each mount a distinct target path.","If the intent is to replace an existing mount, remove the old one first with `--mount-rm <target>` then add the new source for the same target.","Dedupe the mount list by target before issuing the update."],"exampleFix":"// before\ndocker service update \\\n  --mount-add type=bind,src=/a,target=/data \\\n  --mount-add type=volume,src=vol,target=/data web\n\n// after\ndocker service update \\\n  --mount-add type=bind,src=/a,target=/data \\\n  --mount-add type=volume,src=vol,target=/cache web","handlingStrategy":"validation","validationCode":"// Dedupe mount targets before building the --mount-add list.\nseen := map[string]struct{}{}\nfor _, m := range mounts {\n\tif _, dup := seen[m.Target]; dup {\n\t\treturn fmt.Errorf(\"duplicate mount target %q\", m.Target)\n\t}\n\tseen[m.Target] = struct{}{}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Key every mount list by target path when rendering from templates.","When replacing a mount, pair --mount-rm <target> with --mount-add rather than double-adding.","Lint Compose/spec files for duplicate volume destinations."],"tags":["docker","swarm","service","mounts","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}