docker/cli · error · invalidParameterErr

network is specified multiple times

Error message

network %q is specified multiple times

What it means

Returned in opts.go:791 when the same network target name appears more than once in the --network arguments. Each endpoint target must be unique; duplicates are rejected as an invalid parameter so that the daemon receives an unambiguous endpoint set.

Solutions

  1. List each network only once.
  2. If you need multiple attachments to the same network, that is not supported; use distinct networks.
  3. De-duplicate network names before building the command line.

Example fix

# before
docker run --network appnet --network appnet alpine

# after
docker run --network appnet --network sidecarnet alpine
Defensive patterns

Strategy: validation

Validate before calling

func dedupeNetworks(specs []string) ([]string, error) {
    seen := map[string]bool{}
    var out []string
    for _, s := range specs {
        name := strings.SplitN(s, ":", 2)[0]
        if seen[name] { return nil, fmt.Errorf("network %q duplicated", name) }
        seen[name] = true; out = append(out, s)
    }
    return out, nil
}

Try / catch

// Duplicate detection is deterministic; dedupe before invoking.
if specs, err := dedupeNetworks(specs); err != nil { /* report */ } else { use(specs) }

Prevention

When it happens

Trigger: `docker run --network mynet --network mynet ...` (same target twice), or a composable setup that appends the same network more than once.

Common situations: A wrapper script or compose translation that repeats the primary network, or merging multiple --network flags that resolve to the same name.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/b87230a2ca7882b1. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/container/opts.go:791

		} else {
			hasNonUserDefined = true
		}
		if i == 0 {
			// The first network corresponds with what was previously the "only"
			// network, and what would be used when using the non-advanced syntax
			// `--network-alias`, `--link`, `--ip`, `--ip6`, and `--link-local-ip`
			// are set on this network, to preserve backward compatibility with
			// the non-advanced notation
			if err := applyContainerOptions(&n, copts); err != nil {
				return nil, err
			}
		}
		ep, err := parseNetworkAttachmentOpt(n)
		if err != nil {
			return nil, err
		}
		if _, ok := endpoints[n.Target]; ok {
			return nil, invalidParameter(fmt.Errorf("network %q is specified multiple times", n.Target))
		}

		// For backward compatibility: if no custom options are provided for the network,
		// and only a single network is specified, omit the endpoint-configuration
		// on the client (the daemon will still create it when creating the container)
		if i == 0 && len(copts.netMode.Value()) == 1 {
			if ep == nil || reflect.ValueOf(*ep).IsZero() {
				continue
			}
		}
		endpoints[n.Target] = ep
	}
	if hasUserDefined && hasNonUserDefined {
		return nil, invalidParameter(errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes"))
	}
	return endpoints, nil
}

View on GitHub (pinned to 4f84911bfe)