docker/cli · error
duplicate generic-resource `%+v` for service task
Error message
duplicate generic-resource `%+v` for service task
What it means
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.
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.
Example fix
// before docker service create --name gpu --generic-resource GPU=1 --generic-resource GPU=2 nginx // after docker service create --name gpu --generic-resource GPU=2 nginx
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate that each generic-resource Kind appears once before calling ParseGenericResources / addGenericResources.
func uniqueGenericKinds(specs []string) error {
seen := map[string]bool{}
for _, s := range specs {
k, _, ok := strings.Cut(s, "=")
if !ok {
return fmt.Errorf("missing '=' in %q", s)
}
k = strings.TrimSpace(k)
if seen[k] {
return fmt.Errorf("duplicate generic-resource %q for service task", k)
}
seen[k] = true
}
return nil
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid generic-resource format
- invalid generic resource specification
- invalid generic-resource request
- other flags may not be combined with --rollback
- duplicate mount target
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/ef8e54a13f5dda86.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/service/generic_resource_opts.go:61
res.NamedResourceSpec.Kind, res.NamedResourceSpec.Value,
)
}
}
return swarmResources, nil
}
func buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swarm.GenericResource, error) {
m := make(map[string]swarm.GenericResource)
for _, res := range genericRes {
if res.DiscreteResourceSpec == nil {
return nil, fmt.Errorf("invalid generic-resource `%+v` for service task", res)
}
_, ok := m[res.DiscreteResourceSpec.Kind]
if ok {
return nil, fmt.Errorf("duplicate generic-resource `%+v` for service task", res.DiscreteResourceSpec.Kind)
}
m[res.DiscreteResourceSpec.Kind] = res
}
return m, nil
}
func buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource {
l := make([]swarm.GenericResource, 0, len(genericRes))
for _, res := range genericRes {
l = append(l, res)
}
return l
}
View on GitHub (pinned to 4f84911bfe)