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

  1. Check the wrapped error / poller failure details for the ARM operation error code
  2. If InUseCannotBeDeleted, dissociate the IP from its NIC or load balancer and retry Delete
  3. Re-run deletion — re-invoking Delete on an already-deleting/deleted resource is safe (idempotent)
  4. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/4a08e184cd191bbd. Report an issue: GitHub.