{"record":{"id":"ef8e54a13f5dda86","repo":"docker/cli","slug":"duplicate-generic-resource-v-for-service-task","errorCode":null,"errorMessage":"duplicate generic-resource `%+v` for service task","messagePattern":"duplicate generic-resource `%\\+v` for service task","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/service/generic_resource_opts.go","lineNumber":61,"sourceCode":"\t\t\t\tres.NamedResourceSpec.Kind, res.NamedResourceSpec.Value,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn swarmResources, nil\n}\n\nfunc buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swarm.GenericResource, error) {\n\tm := make(map[string]swarm.GenericResource)\n\n\tfor _, res := range genericRes {\n\t\tif res.DiscreteResourceSpec == nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid generic-resource `%+v` for service task\", res)\n\t\t}\n\n\t\t_, ok := m[res.DiscreteResourceSpec.Kind]\n\t\tif ok {\n\t\t\treturn nil, fmt.Errorf(\"duplicate generic-resource `%+v` for service task\", res.DiscreteResourceSpec.Kind)\n\t\t}\n\n\t\tm[res.DiscreteResourceSpec.Kind] = res\n\t}\n\n\treturn m, nil\n}\n\nfunc buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource {\n\tl := make([]swarm.GenericResource, 0, len(genericRes))\n\n\tfor _, res := range genericRes {\n\t\tl = append(l, res)\n\t}\n\n\treturn l\n}\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/service/generic_resource_opts.go#L43-L79","documentation":"Thrown by buildGenericResourceMap in generic_resource_opts.go:61 while constructing a map keyed by DiscreteResourceSpec.Kind. Generic resources are user-defined node resources (e.g. NVIDIA GPUs, Intel FPGAs) advertised on nodes and reserved by a service. The map enforces that each discrete resource Kind appears at most once in a service's reservation list; a second entry for the same Kind is rejected because it would be ambiguous.","triggerScenarios":"Calling 'docker service create'/'docker service update' with multiple --generic-resource (alias --reserve-resource) flags resolving to the same Kind, e.g. '--generic-resource GPU=1 --generic-resource GPU=2'. Also fires during '--generic-resource-add' on update when the service already reserves that Kind, because addGenericResources merges new resources into the existing map.","commonSituations":"Copy-pasting resource flags; merging compose files that list a resource twice; scripting flag accumulation that appends rather than replaces; misunderstanding that a discrete resource is a single count rather than one flag per unit.","solutions":["Inspect current reservations with 'docker service inspect <svc>' and remove the duplicate Kind so each appears once.","To request more of a discrete resource, increase the single value (e.g. '--generic-resource GPU=2') instead of repeating the flag.","If updating, use '--generic-resource-rm GPU' first, then '--generic-resource-add GPU=<n>' to replace cleanly."],"exampleFix":"// before\ndocker service create --name gpu --generic-resource GPU=1 --generic-resource GPU=2 nginx\n// after\ndocker service create --name gpu --generic-resource GPU=2 nginx","handlingStrategy":"validation","validationCode":"// Pre-validate that each generic-resource Kind appears once before calling ParseGenericResources / addGenericResources.\nfunc uniqueGenericKinds(specs []string) error {\n\tseen := map[string]bool{}\n\tfor _, s := range specs {\n\t\tk, _, ok := strings.Cut(s, \"=\")\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"missing '=' in %q\", s)\n\t\t}\n\t\tk = strings.TrimSpace(k)\n\t\tif seen[k] {\n\t\t\treturn fmt.Errorf(\"duplicate generic-resource %q for service task\", k)\n\t\t}\n\t\tseen[k] = true\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Maintain generic resources as a single canonical map of Kind->count and render flags from it.","Diff against the service's existing reservations before adding so you never re-add a Kind.","In automation, deduplicate Kind tokens before constructing the CLI invocation."],"tags":["generic-resource","swarm","validation","service"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}