{"record":{"id":"c1b5070ea6effd4f","repo":"kubernetes/kops","slug":"could-not-delete-port-q-v","errorCode":null,"errorMessage":"could not delete port %q: %v","messagePattern":"could not delete port %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/cloud.go","lineNumber":635,"sourceCode":"}\n\nfunc deletePorts(c OpenstackCloud, instanceGroupName string, clusterName string) error {\n\ttags := []string{\n\t\tfmt.Sprintf(\"%s=%s\", TagClusterName, clusterName),\n\t\tfmt.Sprintf(\"%s=%s\", TagKopsInstanceGroup, instanceGroupName),\n\t}\n\n\tports, err := c.ListPorts(ports.ListOpts{Tags: strings.Join(tags, \",\")})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not list ports %v\", err)\n\t}\n\n\tfor _, port := range ports {\n\t\tklog.V(2).Infof(\"Delete port '%s' (%s)\", port.Name, port.ID)\n\t\terr := c.DeletePort(port.ID)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not delete port %q: %v\", port.ID, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc deleteGroup(c OpenstackCloud, g *cloudinstances.CloudInstanceGroup) error {\n\tcluster := g.Raw.(*kops.Cluster)\n\tallInstances, err := c.ListInstances(servers.ListOpts{\n\t\tName: fmt.Sprintf(\"^%s\", g.InstanceGroup.Name),\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tinstances := []servers.Server{}\n\tfor _, instance := range allInstances {\n\t\tif !InstanceInClusterAndIG(instance, cluster.Name, g.InstanceGroup.Name) {","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/cloud.go#L617-L653","documentation":"Wrapped error returned while deleting OpenStack Neutron ports belonging to an instance group during cluster teardown. kOps enumerates the group's ports and calls DeletePort for each; if the Neutron API rejects or fails a single port deletion, the whole operation aborts with this message wrapping the port ID and underlying error.","triggerScenarios":"DeletePort(port.ID) returns a non-nil error, typically a 404 (port already gone), 409 (port in use by an active instance/DHCP), or a network/auth failure against the Neutron endpoint.","commonSituations":"Port already deleted by a parallel cleanup or manual run; instance still holding the port (must delete instance first); Neutron quota or connectivity issues; stale credentials after Keystone token expiry.","solutions":["Check the wrapped %v error for the HTTP status; if 404, the port is already gone and the group cleanup can be re-run safely","Ensure instances in the group are deleted before ports (kOps deletes instances first in deleteInstanceGroup)","Re-run kops delete after the conflict clears; 409 errors are usually transient while resources detach","Verify OS_* cloud credentials and Neutron endpoint reachability"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before teardown\nports, _ := c.ListPorts(network.ListOpts{})\nfor _, p := range ports {\n    if attached(p.DeviceID) { klog.Infof(\"port %s still attached; delete instances first\", p.ID) }\n}","typeGuard":null,"tryCatchPattern":"// Go: check wrapped error and classify\nif err := c.DeletePort(port.ID); err != nil {\n    var gErr gophercloud.ErrUnexpectedResponseCode\n    if errors.As(err, &gErr) && gErr.Actual == 404 { continue /* already gone */ }\n    return fmt.Errorf(\"could not delete port %q: %v\", port.ID, err)\n}","preventionTips":["Always delete instances before ports","Re-run idempotent delete passes instead of failing hard on 404","Keep Neutron credentials/quota valid before teardown","Check for parallel kops runs to avoid delete races"],"tags":["openstack","neutron","port-deletion","teardown"],"backgroundTag":"openstack-resource-deletion-failed","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"}