{"record":{"id":"c0e2c810e94ef47b","repo":"kubernetes/kops","slug":"error-deleting-network-v","errorCode":null,"errorMessage":"error deleting network: %v","messagePattern":"error deleting network: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/network.go","lineNumber":226,"sourceCode":"\t})\n\tif err != nil {\n\t\treturn n, err\n\t} else if done {\n\t\treturn n, nil\n\t} else {\n\t\treturn n, wait.ErrWaitTimeout\n\t}\n}\n\nfunc (c *openstackCloud) DeleteNetwork(networkID string) error {\n\treturn deleteNetwork(c, networkID)\n}\n\nfunc deleteNetwork(c OpenstackCloud, networkID string) error {\n\tdone, err := vfs.RetryWithBackoff(deleteBackoff, func() (bool, error) {\n\t\terr := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr()\n\t\tif err != nil && !isNotFound(err) {\n\t\t\treturn false, fmt.Errorf(\"error deleting network: %v\", err)\n\t\t}\n\t\tif isNotFound(err) {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t} else if done {\n\t\treturn nil\n\t} else {\n\t\treturn wait.ErrWaitTimeout\n\t}\n}\n","sourceCodeStart":208,"sourceCodeEnd":241,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/network.go#L208-L241","documentation":"This error wraps the failure returned by the OpenStack Neutron API when a network deletion call fails inside deleteNetwork (upup/pkg/fi/cloudup/openstack/network.go:226). The call is retried with deleteBackoff, and only non-404 errors are surfaced; a NotFound is treated as success. It means Neutron refused or failed to delete the network.","triggerScenarios":"networks.Delete(...).ExtractErr() returns an error other than NotFound — e.g. the network still has attached ports/subnets/routers, the network ID does not exist but the API returns a non-404 auth/quota error, or Neutron returns 409/500.","commonSituations":"Tearing down a cluster where instance ports were not yet deleted so Neutron blocks network deletion; stale networks left behind by previous failed deletes; expired or insufficient credentials causing 401/403 during destroy; Neutron service outage or misconfigured region/endpoint.","solutions":["Ensure all ports, subnets, routers, and floating IPs attached to the network are deleted first — Neutron will not delete a network with dependent resources.","Re-run the destroy; deleteNetwork retries with backoff, so transient Neutron errors often clear.","Verify OS_* credentials and project/tenant scope allow deleting networks in the target project.","Check Neutron API health and logs for the underlying 4xx/5xx code embedded in the wrapped error message."],"exampleFix":"// before\nerr := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr()\n// after — clean dependencies first, then delete\nfor _, p := range listPorts(c, ports.ListOpts{NetworkID: networkID}) {\n    if err := deletePort(c, p.ID); err != nil { return err }\n}\nerr := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr()","handlingStrategy":"retry","validationCode":"// Pre-check: ensure the network has no dependent resources before deleting\nports, _ := listPorts(c, ports.ListOpts{NetworkID: networkID})\nsubnets, _ := listSubnets(c, subnets.ListOpts{NetworkID: networkID})\nif len(ports) > 0 || len(subnets) > 0 {\n    return fmt.Errorf(\"network %s still has %d ports and %d subnets; delete them first\", networkID, len(ports), len(subnets))\n}","typeGuard":null,"tryCatchPattern":"// deleteNetwork already retries with vfs.RetryWithBackoff; treat NotFound as success\nerr := deleteNetwork(c, networkID)\nif err != nil {\n    if strings.Contains(err.Error(), \"409\") {\n        // dependent resources still exist — clean them up and retry\n    }\n    return fmt.Errorf(\"network %s could not be deleted: %w\", networkID, err)\n}","preventionTips":["Always delete ports, subnets, routers and floating IPs before the network during teardown.","Reuse the built-in RetryWithBackoff delete flow rather than calling Neutron once.","Verify destroy-time credentials have network delete permissions in the project.","Watch for leaked networks after failed deletes and clean them manually before retrying."],"tags":["openstack","neutron","network-deletion","cloud"],"backgroundTag":"openstack-network-delete-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"}