kubernetes/kops · error
error deleting network: %v
Error message
error deleting network: %v
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/openstack/network.go:226
})
if err != nil {
return n, err
} else if done {
return n, nil
} else {
return n, wait.ErrWaitTimeout
}
}
func (c *openstackCloud) DeleteNetwork(networkID string) error {
return deleteNetwork(c, networkID)
}
func deleteNetwork(c OpenstackCloud, networkID string) error {
done, err := vfs.RetryWithBackoff(deleteBackoff, func() (bool, error) {
err := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr()
if err != nil && !isNotFound(err) {
return false, fmt.Errorf("error deleting network: %v", err)
}
if isNotFound(err) {
return true, nil
}
return false, nil
})
if err != nil {
return err
} else if done {
return nil
} else {
return wait.ErrWaitTimeout
}
}
View on GitHub (pinned to 4c8573c808)
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.
Example fix
// before
err := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr()
// after — clean dependencies first, then delete
for _, p := range listPorts(c, ports.ListOpts{NetworkID: networkID}) {
if err := deletePort(c, p.ID); err != nil { return err }
}
err := networks.Delete(context.TODO(), c.NetworkingClient(), networkID).ExtractErr() Defensive patterns
Strategy: retry
Validate before calling
// Pre-check: ensure the network has no dependent resources before deleting
ports, _ := listPorts(c, ports.ListOpts{NetworkID: networkID})
subnets, _ := listSubnets(c, subnets.ListOpts{NetworkID: networkID})
if len(ports) > 0 || len(subnets) > 0 {
return fmt.Errorf("network %s still has %d ports and %d subnets; delete them first", networkID, len(ports), len(subnets))
} Try / catch
// deleteNetwork already retries with vfs.RetryWithBackoff; treat NotFound as success
err := deleteNetwork(c, networkID)
if err != nil {
if strings.Contains(err.Error(), "409") {
// dependent resources still exist — clean them up and retry
}
return fmt.Errorf("network %s could not be deleted: %w", networkID, err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error describing Network: %v
- network %q not found
- error building neutron client: %w
- could not establish floating network id
- error listing subnets in network %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c0e2c810e94ef47b.
Report an issue: GitHub.