kubernetes/kops · error
deleting public ip address: %w
Error message
deleting public ip address: %w
What it means
Wraps the synchronous error from network.PublicIPAddressesClient.BeginDelete. This is the immediate ARM rejection of the delete request — not the asynchronous poll, which produces a separate 'waiting for...' error. The wrapped *azcore.ResponseError carries the ARM error code.
Source
Thrown at upup/pkg/fi/cloudup/azure/publicipaddress.go:78
pager := c.c.NewListPager(resourceGroupName, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
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 ResponseError: if ResourceNotFound, treat the IP as already deleted and continue
- Dissociate the IP from any NIC/load balancer before deleting
- Verify the identity has Contributor/Delete permission (Microsoft.Network/publicIPAddresses/delete)
- Confirm resourceGroupName and publicIPAddressName match the cluster's tags and Azure naming scheme
Defensive patterns
Strategy: type-guard
Validate before calling
// verify permissions and existence beforehand az group show -n $RG -o none # ensures group exists and identity can read az role assignment list --assignee $PRINCIPAL --include-inherited -o table # ensure delete rights
Type guard
func isNotFound(err error) bool {
var re *azcore.ResponseError
return errors.As(err, &re) && (re.ErrorCode == "ResourceNotFound" || re.StatusCode == 404)
} Try / catch
err := client.Delete(ctx, rg, name)
var re *azcore.ResponseError
if errors.As(err, &re) && re.StatusCode == 404 { return nil /* already deleted */ }
if err != nil { return fmt.Errorf("delete public ip: %w", err) } Prevention
- Treat 404/ResourceNotFound from BeginDelete as success for idempotent teardown
- Dissociate IPs from NICs/load balancers before deleting
- Ensure Contributor role for the kOps identity
- Match names via kOps cluster tags rather than hard-coded strings
When it happens
Trigger: Calling Delete(ctx, resourceGroupName, publicIPAddressName) when c.c.BeginDelete fails immediately: public IP does not exist (ResourceNotFound), name/rg mismatch, RBAC denies Microsoft.Network/publicIPAddresses/delete, or the IP is associated with a NIC/load balancer blocking deletion.
Common situations: Deleting a cluster twice (IP already gone); trying to delete a public IP still attached to a load balancer; identity missing Contributor role; typo'd resource group after a region change.
Related errors
- deleting resource group: %w
- deleting VMSS: %w
- DeleteGroup not implemented on azureCloud
- malformed format of PublicIPAddress ID: %s, %d
- deleting disk: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/62f29a60351c78ed.
Report an issue: GitHub.