kubernetes/kops · error
waiting for public ip address deletion completion: %w
Error message
waiting for public ip address deletion completion: %w
What it means
Wraps the error from future.PollUntilDone after BeginDelete succeeded, i.e. the asynchronous deletion of the public IP failed or was interrupted while polling. Causes include the poller being cancelled (context cancellation), the long-running operation failing server-side, or timeout of the default retry policy.
Source
Thrown at upup/pkg/fi/cloudup/azure/publicipaddress.go:81
if err != nil {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) && respErr.ErrorCode == "ResourceGroupNotFound" {
return nil, nil
}
return nil, fmt.Errorf("listing public ip addresses: %w", err)
}
l = append(l, resp.Value...)
}
return l, nil
}
func (c *publicIPAddressesClientImpl) Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) error {
future, err := c.c.BeginDelete(ctx, resourceGroupName, publicIPAddressName, nil)
if err != nil {
return fmt.Errorf("deleting public ip address: %w", err)
}
if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("waiting for public ip address deletion completion: %w", err)
}
return nil
}
func newPublicIPAddressesClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*publicIPAddressesClientImpl, error) {
c, err := network.NewPublicIPAddressesClient(subscriptionID, cred, nil)
if err != nil {
return nil, fmt.Errorf("creating public ip addresses client: %w", err)
}
return &publicIPAddressesClientImpl{
c: c,
}, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Check the wrapped error / poller failure details for the ARM operation error code
- If InUseCannotBeDeleted, dissociate the IP from its NIC or load balancer and retry Delete
- Re-run deletion — re-invoking Delete on an already-deleting/deleted resource is safe (idempotent)
- Pass a context with sufficient timeout to cover Azure LRO completion
Defensive patterns
Strategy: retry
Validate before calling
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() // give the LRO enough time before starting Delete
Type guard
func isInUseError(err error) bool {
var re *azcore.ResponseError
return errors.As(err, &re) && strings.Contains(re.ErrorCode, "InUse")
} Try / catch
err := client.Delete(ctx, rg, name)
if err != nil {
if isInUseError(err) { /* dissociate then retry Delete */ }
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { /* resubmit; deletion continues server-side */ }
} Prevention
- Use a long context timeout for LRO polling
- Retry Delete on transient failures — it is idempotent
- Check for InUseCannotBeDeleted and dissociate first
- Avoid Ctrl-C'ing mid-teardown; let the poller finish
When it happens
Trigger: BeginDelete accepted the LRO, then PollUntilDone(ctx, nil) observes the operation fail (ARM operation-level error, e.g. InUseCannotBeDeleted) or the ctx is cancelled/times out before the deletion completes.
Common situations: kOps context cancelled by Ctrl-C or parent timeout while tearing down a cluster; Azure reports the IP still bound to a NIC/LB (InUseCannotBeDeleted); transient ARM 5xx during the poll.
Related errors
- waiting for resource group deletion completion: %w
- waiting for virtual network deletion completion: %w
- waiting for VMSS deletion completion: %w
- DeleteGroup not implemented on azureCloud
- waiting for disk create/update completion: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4a08e184cd191bbd.
Report an issue: GitHub.