kubernetes/kops · critical

creating VMSSs client: %w

Error message

creating VMSSs client: %w

What it means

This error is returned when the Azure SDK fails to construct compute.NewVirtualMachineScaleSetsClient (the ARM client object) for the given subscriptionID and credential. This happens almost exclusively during client instantiation/parameter validation inside the SDK — not when making API calls. It is surfaced during newAzureCloud, so an Azure cluster build fails immediately at cloud-init time.

Source

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

	}
	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

  1. Ensure AZURE_SUBSCRIPTION_ID is set and non-empty before running kops (echo $AZURE_SUBSCRIPTION_ID)
  2. Verify the azidentity.DefaultAzureCredential was constructed without error and is non-nil before passing it in
  3. Run az account show to confirm the subscription ID matches the intended tenant
  4. Check go.mod for consistent azure-sdk-for-go / azcore module versions; run make gomod to reconcile
  5. If constructing clients in custom code, validate subscriptionID with a regex before calling the SDK

Example fix

// before
cred, _ := azidentity.NewDefaultAzureCredential(nil)
client, err := azure.NewCloud(ctx, "", cred) // empty subscriptionID
// after
if os.Getenv("AZURE_SUBSCRIPTION_ID") == "" {
	return fmt.Errorf("AZURE_SUBSCRIPTION_ID must be set")
}
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil { return err }
client, err := azure.NewCloud(ctx, os.Getenv("AZURE_SUBSCRIPTION_ID"), cred)
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate inputs before constructing Azure clients
subID := os.Getenv("AZURE_SUBSCRIPTION_ID")
if subID == "" {
	return fmt.Errorf("AZURE_SUBSCRIPTION_ID must be set")
}
if !regexp.MustCompile(`^[0-9a-fA-F-]{36}$`).MatchString(subID) {
	return fmt.Errorf("AZURE_SUBSCRIPTION_ID %q is not a valid UUID", subID)
}
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil || cred == nil {
	return fmt.Errorf("building Azure credential: %w", err)
}

Type guard

func validSubscriptionID(s string) bool {
	re := regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
	return re.MatchString(strings.ToLower(s))
}

Prevention

When it happens

Trigger: newVMScaleSetsClientImpl calls compute.NewVirtualMachineScaleSetsClient(subscriptionID, cred, nil) and the SDK returns an error: nil credential, invalid/empty subscriptionID, or internal SDK failure building the client pipeline (rare; e.g. bad client options).

Common situations: AZURE_SUBSCRIPTION_ID unset or empty in the environment so an empty subscriptionID is passed; DefaultAzureCredential construction succeeded but returned a nil/degenerate credential; version mismatch between azure-sdk-for-go modules (mismatched azcore versions) breaking client construction; programmatic use passing an uninitialized credential.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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