{"record":{"id":"722a4a65fc6c4e66","repo":"kubernetes/kops","slug":"getting-vmss-w","errorCode":null,"errorMessage":"getting VMSS: %w","messagePattern":"getting VMSS: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/vmscaleset.go","lineNumber":83,"sourceCode":"\t\tif err != nil {\n\t\t\tvar respErr *azcore.ResponseError\n\t\t\tif errors.As(err, &respErr) && respErr.ErrorCode == \"ResourceGroupNotFound\" {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"listing VMSSs: %w\", err)\n\t\t}\n\t\tl = append(l, resp.Value...)\n\t}\n\treturn l, nil\n}\n\nfunc (c *vmScaleSetsClientImpl) Get(ctx context.Context, resourceGroupName string, vmssName string) (*compute.VirtualMachineScaleSet, error) {\n\topts := &compute.VirtualMachineScaleSetsClientGetOptions{\n\t\tExpand: to.Ptr(compute.ExpandTypesForGetVMScaleSetsUserData),\n\t}\n\tresp, err := c.c.Get(ctx, resourceGroupName, vmssName, opts)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting VMSS: %w\", err)\n\t}\n\treturn &resp.VirtualMachineScaleSet, nil\n}\n\nfunc (c *vmScaleSetsClientImpl) Delete(ctx context.Context, resourceGroupName, vmssName string) error {\n\tfuture, err := c.c.BeginDelete(ctx, resourceGroupName, vmssName, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"deleting VMSS: %w\", err)\n\t}\n\tif _, err := future.PollUntilDone(ctx, nil); err != nil {\n\t\treturn fmt.Errorf(\"waiting for VMSS deletion completion: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc newVMScaleSetsClientImpl(subscriptionID string, cred *azidentity.DefaultAzureCredential) (*vmScaleSetsClientImpl, error) {\n\tc, err := compute.NewVirtualMachineScaleSetsClient(subscriptionID, cred, nil)\n\tif err != nil {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/vmscaleset.go#L65-L101","documentation":"This error wraps any failure from the Azure SDK VirtualMachineScaleSetsClient.Get call when kOps fetches a VMSS definition (with UserData expanded) from an Azure resource group. It is a thin wrapper: the underlying azcore/azidentity error (404, 401, 403, throttling, network) is preserved via %w. kOps throws it so callers can identify the operation (reading a scale set) while retaining the original SDK error for errors.Is/As inspection.","triggerScenarios":"vmScaleSetsClientImpl.Get is invoked while resolving or verifying a VMSS (e.g. during Azure cluster reconciliation or instance group operations) and the ARM API call fails: VMSS does not exist in the given resource group, subscription mismatch, RBAC lacks 'Reader' on the scale set, ARM throttling (429), or transient network/DNS failure reaching management.azure.com.","commonSituations":"Typo in the VMSS name or resource group in kOps cluster spec; cluster spec references a scale set deleted out-of-band in the Azure portal; azidentity credentials not authorized for the subscription (wrong AZURE_TENANT_ID/AZURE_SUBSCRIPTION_ID env vars); corporate proxy blocking ARM endpoints; ARM API throttling on very large clusters.","solutions":["Verify the VMSS name and resource group are correct: az vmss list -g <resourceGroup> -o table","Confirm RBAC: grant the identity 'Contributor' (or at least Reader) on the cluster resource group","Check AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID and credential env vars match the cluster's subscription","Unwrap with errors.As to check azcore.ResponseError and inspect StatusCode (404 vs 401/429) to pick the right fix","Retry if the error is 429 or a transient network failure"],"exampleFix":"// before\nvmss, err := cloud.AzureCloud().VMScaleSets().Get(ctx, rg, vmssName)\nif err != nil { return fmt.Errorf(\"getting VMSS: %w\", err) }\n// after\nvmss, err := cloud.AzureCloud().VMScaleSets().Get(ctx, rg, vmssName)\nif err != nil {\n\tvar respErr *azcore.ResponseError\n\tif errors.As(err, &respErr) && respErr.StatusCode == 404 {\n\t\treturn nil // treat as not-found instead of aborting\n\t}\n\treturn fmt.Errorf(\"getting VMSS %q in rg %q: %w\", vmssName, rg, err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: verify preconditions before the ARM call\nif vmssName == \"\" || resourceGroupName == \"\" {\n\treturn fmt.Errorf(\"VMSS name and resource group must be non-empty\")\n}\n// optionally: rgExists, _ := groupsClient.Get(ctx, resourceGroupName, nil)\n// if rgExists.StatusCode == 404 { return fmt.Errorf(\"resource group %q missing\", resourceGroupName) }","typeGuard":"func isNotFoundErr(err error) bool {\n\tvar respErr *azcore.ResponseError\n\treturn errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound\n}","tryCatchPattern":"vmss, err := client.Get(ctx, rg, vmssName)\nif err != nil {\n\tvar respErr *azcore.ResponseError\n\tswitch {\n\tcase errors.As(err, &respErr) && respErr.StatusCode == 404:\n\t\treturn nil // handle not-found gracefully\n\tcase errors.As(err, &respErr) && respErr.StatusCode == 429:\n\t\t// back off and retry per Retry-After header\n\tdefault:\n\t\treturn fmt.Errorf(\"getting VMSS: %w\", err)\n\t}\n}","preventionTips":["Validate VMSS/resource-group names against the cluster spec before ARM calls","Grant the kOps identity at least Reader on the cluster resource group","Set AZURE_SUBSCRIPTION_ID/TENANT_ID correctly in every environment (CI, local)","Check azcore.ResponseError.StatusCode to distinguish 404/401/429 handling","Wrap ARM calls with bounded retry/backoff for 429 and transient errors"],"tags":["azure","vmss","api-error","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-12T07:17:12.445Z"}