kubernetes/kops · error

getting VMSS: %w

Error message

getting VMSS: %w

What it means

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.

Source

Thrown at upup/pkg/fi/cloudup/azure/vmscaleset.go:83

		if err != nil {
			var respErr *azcore.ResponseError
			if errors.As(err, &respErr) && respErr.ErrorCode == "ResourceGroupNotFound" {
				return nil, nil
			}
			return nil, fmt.Errorf("listing VMSSs: %w", err)
		}
		l = append(l, resp.Value...)
	}
	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 {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the VMSS name and resource group are correct: az vmss list -g <resourceGroup> -o table
  2. Confirm RBAC: grant the identity 'Contributor' (or at least Reader) on the cluster resource group
  3. Check AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID and credential env vars match the cluster's subscription
  4. Unwrap with errors.As to check azcore.ResponseError and inspect StatusCode (404 vs 401/429) to pick the right fix
  5. Retry if the error is 429 or a transient network failure

Example fix

// before
vmss, err := cloud.AzureCloud().VMScaleSets().Get(ctx, rg, vmssName)
if err != nil { return fmt.Errorf("getting VMSS: %w", err) }
// after
vmss, err := cloud.AzureCloud().VMScaleSets().Get(ctx, rg, vmssName)
if err != nil {
	var respErr *azcore.ResponseError
	if errors.As(err, &respErr) && respErr.StatusCode == 404 {
		return nil // treat as not-found instead of aborting
	}
	return fmt.Errorf("getting VMSS %q in rg %q: %w", vmssName, rg, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify preconditions before the ARM call
if vmssName == "" || resourceGroupName == "" {
	return fmt.Errorf("VMSS name and resource group must be non-empty")
}
// optionally: rgExists, _ := groupsClient.Get(ctx, resourceGroupName, nil)
// if rgExists.StatusCode == 404 { return fmt.Errorf("resource group %q missing", resourceGroupName) }

Type guard

func isNotFoundErr(err error) bool {
	var respErr *azcore.ResponseError
	return errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound
}

Try / catch

vmss, err := client.Get(ctx, rg, vmssName)
if err != nil {
	var respErr *azcore.ResponseError
	switch {
	case errors.As(err, &respErr) && respErr.StatusCode == 404:
		return nil // handle not-found gracefully
	case errors.As(err, &respErr) && respErr.StatusCode == 429:
		// back off and retry per Retry-After header
	default:
		return fmt.Errorf("getting VMSS: %w", err)
	}
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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