{"record":{"id":"daf61fda72013470","repo":"kubernetes/kops","slug":"found-multiple-interfaces-which-subnet-s-attach-t","errorCode":null,"errorMessage":"found multiple interfaces which subnet:%s attach to","messagePattern":"found multiple interfaces which subnet:(.+?) attach to","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstacktasks/routerinterface.go","lineNumber":80,"sourceCode":"\t\tDeviceID:  fi.ValueOf(i.Router.ID),\n\t\tID:        fi.ValueOf(i.ID),\n\t}\n\tps, err := cloud.ListPorts(opt)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif ps == nil {\n\t\treturn nil, nil\n\t}\n\n\tvar actual *RouterInterface\n\n\tsubnetID := fi.ValueOf(i.Subnet.ID)\n\tfor _, p := range ps {\n\t\tfor _, ip := range p.FixedIPs {\n\t\t\tif ip.SubnetID == subnetID {\n\t\t\t\tif actual != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"found multiple interfaces which subnet:%s attach to\", subnetID)\n\t\t\t\t}\n\t\t\t\tactual = &RouterInterface{\n\t\t\t\t\tID:        new(p.ID),\n\t\t\t\t\tName:      i.Name,\n\t\t\t\t\tRouter:    i.Router,\n\t\t\t\t\tSubnet:    i.Subnet,\n\t\t\t\t\tLifecycle: i.Lifecycle,\n\t\t\t\t}\n\t\t\t\ti.ID = actual.ID\n\t\t\t}\n\t\t}\n\t}\n\treturn actual, nil\n}\n\nfunc (i *RouterInterface) Run(context *fi.CloudupContext) error {\n\treturn fi.CloudupDefaultDeltaRunMethod(i, context)\n}","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstacktasks/routerinterface.go#L62-L98","documentation":"Raised in RouterInterface.Find (routerinterface.go:80). When reconciling, kOps lists ports attached to the router on the subnet's network and scans their FixedIPs for one matching the task's subnet. If more than one such port/interface is found, the desired state is ambiguous, so it fails rather than guessing which router interface to reuse.","triggerScenarios":"ListPorts filtered by NetworkID + DeviceID (router) returns multiple ports whose FixedIPs include the same SubnetID — i.e., the router has more than one interface on that subnet, usually left over from a previous failed/partial apply or manual `openstack router add subnet` calls.","commonSituations":"A previous `kops update` timed out after creating the interface but before recording the port ID, then a retry added a second interface; an operator manually attached the subnet to the router; duplicated ports from Neutron after a failed interface detach.","solutions":["Inspect the duplicate ports: `openstack port list --device-id <router-id>` and identify ports with fixed IPs in the target subnet","Detach the extra interface: `openstack router remove subnet <router> <subnet>` (or delete the stale port), keeping one","Re-run `kops update cluster` so Find resolves a single interface","Prevent recurrence by never manually adding the cluster subnet to the router outside kOps"],"exampleFix":"// before: two router ports on subnet\n$ openstack port list --device-id <router-id>  # two ports with fixed IPs in subnet X\n// after\n$ openstack router remove subnet <router> <subnet-X>\n$ kops update cluster <name> --yes","handlingStrategy":"validation","validationCode":"// before applying, ensure the router has at most one interface on the subnet\nports, _ := ports.List(netClient, ports.ListOpts{DeviceID: routerID, NetworkID: netID}).AllPages()\ncount := 0\nfor _, p := range ports { for _, ip := range p.FixedIPs { if ip.SubnetID == subnetID { count++ } } }\nif count > 1 { return fmt.Errorf(\"router %s has %d interfaces on subnet %s; detach extras first\", routerID, count, subnetID) }","typeGuard":null,"tryCatchPattern":"if err := kopsUpdate(); err != nil {\n    if strings.Contains(err.Error(), \"found multiple interfaces\") {\n        log.Fatal(\"detach duplicate router interfaces: openstack router remove subnet <router> <subnet>\")\n    }\n    return err\n}","preventionTips":["Never manually add cluster subnets to the router outside kOps","Clean up partially created interfaces after a failed/timed-out apply","Check `openstack port list --device-id <router>` before re-running updates","Let kOps own the full router lifecycle for cluster subnets"],"tags":["openstack","router-interface","ports","neutron"],"backgroundTag":"multiple-matching-resources-found","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}