kubernetes/kops · error
deleting VMSS: %w
Error message
deleting VMSS: %w
What it means
This error wraps the immediate failure of the ARM BeginDelete call that starts deleting a Virtual Machine Scale Set. It fires synchronously when Azure rejects the delete request (auth, RBAC, invalid name, or ARM rejection) — not during polling. The original SDK error is preserved via %w.
Source
Thrown at upup/pkg/fi/cloudup/azure/vmscaleset.go:91
}
return l, nil
}
func (c *vmScaleSetsClientImpl) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) {
opts := &compute.VirtualMachineScaleSetsClientGetOptions{
Expand: to.Ptr(compute.ExpandTypesForGetVMScaleSetsUserData),
}
resp, err := c.c.Get(ctx, resourceGroupName, vmssName, opts)
if err != nil {
return nil, fmt.Errorf("getting VMSS: %w", err)
}
return &resp.VirtualMachineScaleSet, nil
}
func (c *vmScaleSetsClientImpl) Delete(ctx context.Context, resourceGroupName, vmssName string) error {
future, err := c.c.BeginDelete(ctx, resourceGroupName, vmssName, nil)
if err != nil {
return fmt.Errorf("deleting VMSS: %w", err)
}
if _, err := future.PollUntilDone(ctx, nil); err != nil {
return fmt.Errorf("waiting for VMSS deletion completion: %w", err)
}
return nil
}
func newVMScaleSetsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*vmScaleSetsClientImpl, error) {
c, err := compute.NewVirtualMachineScaleSetsClient(subscriptionID, cred, nil)
if err != nil {
return nil, fmt.Errorf("creating VMSSs client: %w", err)
}
return &vmScaleSetsClientImpl{
c: c,
}, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Unwrap with errors.As (*azcore.ResponseError); if StatusCode==404/409, treat as already-deleted or retry idempotently
- Grant the kOps identity 'Virtual Machine Contributor' on the resource group
- Check for concurrent deletes (two CI jobs / reconciliation loops) and add a mutex or retry-on-conflict
- Re-authenticate: refresh credentials and verify AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET or managed identity
- Retry the delete after transient failures; BeginDelete is idempotent for an existing VMSS
Example fix
// before
err := client.Delete(ctx, rg, vmssName)
if err != nil { return err }
// after
err := client.Delete(ctx, rg, vmssName)
if err != nil {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound {
return nil // already deleted
}
return fmt.Errorf("deleting VMSS %q: %w", vmssName, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: confirm existence and RBAC preconditions before deleting
vmss, err := client.Get(ctx, rg, vmssName)
if err != nil {
if isNotFoundErr(err) { return nil } // nothing to delete
return err
} Type guard
func isConflictOrNotFound(err error) bool {
var respErr *azcore.ResponseError
return errors.As(err, &respErr) && (respErr.StatusCode == http.StatusNotFound || respErr.StatusCode == http.StatusConflict)
} Try / catch
err := client.Delete(ctx, rg, vmssName)
if err != nil {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) {
switch respErr.StatusCode {
case 404:
return nil // already deleted — treat as success
case 409, 429:
// retry with backoff / serialize concurrent deletes
default:
return fmt.Errorf("deleting VMSS: %w", err)
}
}
} Prevention
- Avoid concurrent delete pipelines for the same VMSS (serialize teardown jobs)
- Treat 404 on delete as success for idempotent teardown
- Grant 'Virtual Machine Contributor' so BeginDelete is never RBAC-rejected
- Use retry with exponential backoff on 409/429 responses
- Keep credentials fresh for long-running teardown operations
When it happens
Trigger: vmScaleSetsClientImpl.Delete calls compute.VirtualMachineScaleSetsClient.BeginDelete and the request itself fails: identity lacks 'Contributor'/'Virtual Machine Contributor' role, VMSS already gone in a racy delete, resource group name mismatch, or the request never reaches ARM (network/auth failure).
Common situations: Tearing down a cluster while an operator with insufficient RBAC runs kops delete cluster; concurrent delete pipelines racing to remove the same VMSS; deleting a scale set whose parent resource group is mid-deletion; expired azidentity token or misconfigured AZURE_* env vars.
Related errors
- deleting public ip address: %w
- deleting resource group: %w
- deleting role assignment: %w
- getting VMSS: %w
- waiting for VMSS deletion completion: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d1d8fc4eac6c21be.
Report an issue: GitHub.