{"record":{"id":"8dda876de133fc88","repo":"nektos/act","slug":"network-q-is-specified-multiple-times","errorCode":null,"errorMessage":"network %q is specified multiple times","messagePattern":"network %q is specified multiple times","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/docker_cli.go","lineNumber":798,"sourceCode":"\t\t} else {\n\t\t\thasNonUserDefined = true\n\t\t}\n\t\tif i == 0 {\n\t\t\t// The first network corresponds with what was previously the \"only\"\n\t\t\t// network, and what would be used when using the non-advanced syntax\n\t\t\t// `--network-alias`, `--link`, `--ip`, `--ip6`, and `--link-local-ip`\n\t\t\t// are set on this network, to preserve backward compatibility with\n\t\t\t// the non-advanced notation\n\t\t\tif err := applyContainerOptions(&n, copts); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tep, err := parseNetworkAttachmentOpt(n)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, ok := endpoints[n.Target]; ok {\n\t\t\treturn nil, fmt.Errorf(\"network %q is specified multiple times\", n.Target)\n\t\t}\n\n\t\t// For backward compatibility: if no custom options are provided for the network,\n\t\t// and only a single network is specified, omit the endpoint-configuration\n\t\t// on the client (the daemon will still create it when creating the container)\n\t\tif i == 0 && len(copts.netMode.Value()) == 1 {\n\t\t\tif ep == nil || reflect.ValueOf(*ep).IsZero() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tendpoints[n.Target] = ep\n\t}\n\tif hasUserDefined && hasNonUserDefined {\n\t\treturn nil, errors.New(\"conflicting options: cannot attach both user-defined and non-user-defined network-modes\")\n\t}\n\treturn endpoints, nil\n}\n","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/docker_cli.go#L780-L816","documentation":"In the advanced network notation (--network name=net1 with per-network options), each network endpoint is collected into a map keyed by target network name. If the same network target appears twice — e.g. '--network name=net1 --network name=net1' or overlapping long/short forms resolving to the same target — the duplicate key is rejected because Docker cannot attach one endpoint config twice.","triggerScenarios":"Passing the same network more than once via container options: combining a plain --network net1 with an advanced --network name=net1, or literally repeating the advanced form. Detected in act's local parse of container options.","commonSituations":"Workflow options strings concatenating fragments from multiple sources; migrating from single-network to advanced notation without removing the old flag; YAML anchors duplicating option lines.","solutions":["Specify each network exactly once in options","If combining job-level container options and workflow-level options, deduplicate the --network entries","Use the advanced form only when you need per-network aliases/IPs, otherwise a single --network suffices"],"exampleFix":"# before\noptions: --network name=net1 --network name=net1\n\n# after\noptions: --network name=net1","handlingStrategy":"validation","validationCode":"seen := map[string]bool{}\nfor _, n := range networks {\n    if seen[n.Target] {\n        return fmt.Errorf(\"network %q duplicated\", n.Target)\n    }\n    seen[n.Target] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mention each network exactly once in options","When merging option fragments (workflow + job level), deduplicate --network entries","Prefer the simple --network form unless per-network options are needed"],"tags":["docker","network","duplicate","container-options","act"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}