{"record":{"id":"6db4f8f7cf8f060c","repo":"kubernetes/kops","slug":"listing-vmss-vms-w","errorCode":null,"errorMessage":"listing VMSS VMs: %w","messagePattern":"listing VMSS VMs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/vmscalesetvm.go","lineNumber":45,"sourceCode":"// VMScaleSetVMsClient is a client for managing VMs in VM Scale Sets.\ntype VMScaleSetVMsClient interface {\n\tList(ctx context.Context, resourceGroupName, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error)\n\tDelete(ctx context.Context, resourceGroupName, vmssName, instanceId string) error\n}\n\ntype vmScaleSetVMsClientImpl struct {\n\tc *compute.VirtualMachineScaleSetVMsClient\n}\n\nvar _ VMScaleSetVMsClient = (*vmScaleSetVMsClientImpl)(nil)\n\nfunc (c *vmScaleSetVMsClientImpl) List(ctx context.Context, resourceGroupName, vmssName string) ([]*compute.VirtualMachineScaleSetVM, error) {\n\tvar l []*compute.VirtualMachineScaleSetVM\n\tpager := c.c.NewListPager(resourceGroupName, vmssName, nil)\n\tfor pager.More() {\n\t\tresp, err := pager.NextPage(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"listing VMSS VMs: %w\", err)\n\t\t}\n\t\tl = append(l, resp.Value...)\n\t}\n\treturn l, nil\n}\n\nfunc (c *vmScaleSetVMsClientImpl) Delete(ctx context.Context, resourceGroupName, vmssName, instanceId string) error {\n\tfuture, err := c.c.BeginDelete(ctx, resourceGroupName, vmssName, instanceId, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"deleting VMSS VM: %w\", err)\n\t}\n\tif _, err = future.PollUntilDone(ctx, nil); err != nil {\n\t\treturn fmt.Errorf(\"waiting for VMSS VM deletion completion: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc newVMScaleSetVMsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*vmScaleSetVMsClientImpl, error) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/vmscalesetvm.go#L27-L63","documentation":"This error wraps a failure from paginating the ARM VirtualMachineScaleSetVMs List API, which enumerates the VM instances inside a scale set. Any page fetch failure (auth, throttling, VMSS vanished mid-enumeration, network) is wrapped once per pager.NextPage call with the accumulated results discarded. The SDK error is preserved via %w for errors.Is/As inspection.","triggerScenarios":"vmScaleSetVMsClientImpl.List iterates c.c.NewListPager(...).NextPage(ctx) and a page request fails: RBAC lacks read access to the VMSS instances, ARM returns 429 under heavy listing, the parent VMSS is deleted while paging, or a transient network failure occurs between pages.","commonSituations":"kops validating or updating instances of a large scale set and hitting ARM throttling limits (many pages); the scale set was resized/deleted concurrently by another controller mid-list; identity credentials lack 'Reader' on the VM; expired token during long paginations.","solutions":["Unwrap with errors.As (*azcore.ResponseError): retry on 429 honoring Retry-After, return not-found on 404","Reduce list frequency or scope to stay under ARM throttling limits (batch instance operations)","Re-check RBAC: the identity needs Reader/Virtual Machine Contributor on the resource group","Retry the full List — results are discarded on partial failure, so pagination must restart","Ensure the parent VMSS still exists (or handle 404 as an empty list) before enumerating instances"],"exampleFix":"// before\nvms, err := client.List(ctx, rg, vmssName)\nif err != nil { return err }\n// after\nvms, err := client.List(ctx, rg, vmssName)\nif err != nil {\n\tvar respErr *azcore.ResponseError\n\tif errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound {\n\t\treturn nil // VMSS gone: zero instances\n\t}\n\treturn fmt.Errorf(\"listing VMSS %q instances: %w\", vmssName, err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: verify the parent VMSS exists before enumerating its instances\n_, err := scaleSetsClient.Get(ctx, rg, vmssName)\nif err != nil {\n\tif isNotFoundErr(err) { return nil, nil } // no VMSS => zero VMs\n\treturn nil, err\n}","typeGuard":"func isThrottledOrNotFound(err error) (throttled, notFound bool) {\n\tvar respErr *azcore.ResponseError\n\tif !errors.As(err, &respErr) {\n\t\treturn false, false\n\t}\n\treturn respErr.StatusCode == http.StatusTooManyRequests, respErr.StatusCode == http.StatusNotFound\n}","tryCatchPattern":"vms, err := client.List(ctx, rg, vmssName)\nif err != nil {\n\tthrottled, notFound := isThrottledOrNotFound(err)\n\tswitch {\n\tcase notFound:\n\t\treturn nil // VMSS gone: treat as empty instance list\n\tcase throttled:\n\t\t// honor Retry-After and re-run the full pagination\n\tdefault:\n\t\treturn fmt.Errorf(\"listing VMSS VMs: %w\", err)\n\t}\n}","preventionTips":["Treat 404 during listing as an empty result for idempotent reconciliation","Retry the whole pagination on 429 — partial results are discarded inside List","Throttle how often instances are listed on very large scale sets to stay under ARM limits","Keep identity RBAC (Reader+) current on the cluster resource group","Watch token expiry on long paginations; DefaultAzureCredential refreshes automatically but check clock skew"],"tags":["azure","vmss","pagination","throttling","error-wrapping"],"backgroundTag":"azure-sdk-request-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}