kubernetes/kops · error

creating/updating virtual network: %w

Error message

creating/updating virtual network: %w

What it means

Wrapped when the initial BeginCreateOrUpdate call to the Azure VirtualNetworks client fails synchronously — i.e., the request never became a long-running future. The ARM error (invalid parameters, RBAC denial, name conflict, 4xx/5xx) is preserved by %w. It fires before the polling stage that produces the 'waiting for virtual network create/update completion' error.

Source

Thrown at upup/pkg/fi/cloudup/azure/virtualnetwork.go:45

)

// VirtualNetworksClient is a client for managing Virtual Networks.
type VirtualNetworksClient interface {
	CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) (*network.VirtualNetwork, error)
	List(ctx context.Context, resourceGroupName string) ([]*network.VirtualNetwork, error)
	Delete(ctx context.Context, resourceGroupName, vnetName string) error
}

type virtualNetworksClientImpl struct {
	c *network.VirtualNetworksClient
}

var _ VirtualNetworksClient = (*virtualNetworksClientImpl)(nil)

func (c *virtualNetworksClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName string, parameters network.VirtualNetwork) (*network.VirtualNetwork, error) {
	future, err := c.c.BeginCreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, parameters, nil)
	if err != nil {
		return nil, fmt.Errorf("creating/updating virtual network: %w", err)
	}
	vnet, err := future.PollUntilDone(ctx, nil)
	if err != nil {
		return nil, fmt.Errorf("waiting for virtual network create/update completion: %w", err)
	}
	return &vnet.VirtualNetwork, err
}

func (c *virtualNetworksClientImpl) List(ctx context.Context, resourceGroupName string) ([]*network.VirtualNetwork, error) {
	if resourceGroupName == "" {
		return nil, nil
	}

	var l []*network.VirtualNetwork
	pager := c.c.NewListPager(resourceGroupName, nil)
	for pager.More() {
		resp, err := pager.NextPage(ctx)
		if err != nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped azcore.ResponseError for StatusCode and ErrorCode to identify the ARM failure
  2. Verify the service principal has Network Contributor (or Owner) on the resource group
  3. Validate the VirtualNetwork parameters (addressSpace CIDRs, subnets, location) in the kops cluster spec
  4. Ensure the resource group exists and the vnet name/location match the spec

Example fix

// before
VirtualNetwork{ Location: to.Ptr("eastus"), AddressSpace: ... } // CIDR overlaps existing vnet
// after
VirtualNetwork{ Location: to.Ptr("eastus"), AddressSpace: &network.AddressSpace{AddressPrefixes: []*string{to.Ptr("172.16.0.0/12")}} } // unique, non-overlapping CIDR
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: pre-validate vnet parameters before CreateOrUpdate
if parameters.Location == nil || parameters.AddressSpace == nil || len(parameters.AddressSpace.AddressPrefixes) == 0 {
    return fmt.Errorf("virtual network %s/%s missing location or address space", resourceGroupName, virtualNetworkName)
}
// ensure resource group exists
if _, err := rgClient.Get(ctx, resourceGroupName, nil); err != nil {
    return fmt.Errorf("resource group %s not found: %w", resourceGroupName, err)
}

Type guard

func armDenied(err error) bool {
    var respErr *azcore.ResponseError
    return errors.As(err, &respErr) && (respErr.StatusCode == http.StatusForbidden || respErr.StatusCode == http.StatusUnauthorized)
}

Try / catch

vnet, err := vnetsClient.CreateOrUpdate(ctx, rg, name, parameters)
if err != nil {
    var respErr *azcore.ResponseError
    if errors.As(err, &respErr) {
        switch {
        case respErr.StatusCode == http.StatusForbidden:
            return fmt.Errorf("grant Network Contributor on %s: %w", rg, err)
        case respErr.StatusCode == http.StatusConflict:
            return fmt.Errorf("vnet %s already exists/CIDR conflict: %w", name, err)
        }
    }
    return err
}

Prevention

When it happens

Trigger: virtualNetworksClientImpl.CreateOrUpdate calls c.c.BeginCreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, parameters, nil) and the SDK returns an error: invalid VirtualNetwork parameters (bad CIDR, DNS servers), missing networkContributor/write permission on the resource group, wrong resource group or vnet name, or network failure.

Common situations: See trigger scenarios.

Related errors


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