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
- Inspect the wrapped azcore.ResponseError for StatusCode and ErrorCode to identify the ARM failure
- Verify the service principal has Network Contributor (or Owner) on the resource group
- Validate the VirtualNetwork parameters (addressSpace CIDRs, subnets, location) in the kops cluster spec
- 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
- Check the service principal's role assignment (Network Contributor) on the resource group before provisioning
- Ensure vnet CIDRs in the cluster spec don't overlap existing networks
- Create the resource group before the vnet
- Handle 429 with retry-after using azruntime retry options
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
- listing virtual networks: %w
- deleting virtual network: %w
- waiting for virtual network deletion completion: %w
- waiting for virtual network create/update completion: %w
- FindVPCInfo not implemented on azureCloud, use FindVNetInfo
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d9fb9f050c4b082c.
Report an issue: GitHub.