kubernetes/kops · error
found VMSS without IP config subnet ID
Error message
found VMSS without IP config subnet ID
What it means
During Find, kOps reads an existing Azure VM Scale Set from the Azure SDK and validates that its single IP configuration carries a Subnet resource reference with a non-nil ID string. The Subnet ID is required to reconstruct the kops VMScaleSet task (it yields the virtual network and subnet for diffing). If the Azure API returns a subnet subresource whose ID pointer is nil, kOps cannot model the scale set and aborts with this error.
Source
Thrown at upup/pkg/fi/cloudup/azuretasks/vmscaleset.go:147
return nil, fmt.Errorf("expecting exactly 1 network interface config for %q, found %d: %+v", *s.Name, len(nwConfigs), nwConfigs)
}
nwConfig := nwConfigs[0]
if nwConfig.Properties == nil {
return nil, fmt.Errorf("found VMSS without network interface config properties")
}
ipConfigs := nwConfig.Properties.IPConfigurations
if len(ipConfigs) != 1 {
return nil, fmt.Errorf("expecting exactly 1 network interface IP config for %q, found %d: %+v", *s.Name, len(ipConfigs), ipConfigs)
}
ipConfig := ipConfigs[0]
if ipConfig.Properties == nil {
return nil, fmt.Errorf("found VMSS without IP config properties")
}
if ipConfig.Properties.Subnet == nil {
return nil, fmt.Errorf("found VMSS without IP config subnet")
}
if ipConfig.Properties.Subnet.ID == nil {
return nil, fmt.Errorf("found VMSS without IP config subnet ID")
}
subnetID, err := azure.ParseSubnetID(*ipConfig.Properties.Subnet.ID)
if err != nil {
return nil, fmt.Errorf("failed to parse subnet ID %s", *ipConfig.Properties.Subnet.ID)
}
var loadBalancerID *azure.LoadBalancerID
if ipConfig.Properties.LoadBalancerBackendAddressPools != nil {
for _, i := range ipConfig.Properties.LoadBalancerBackendAddressPools {
if !strings.Contains(*i.ID, "api") {
continue
}
loadBalancerID, err = azure.ParseLoadBalancerID(*i.ID)
if err != nil {
return nil, fmt.Errorf("failed to parse loadbalancer ID %s", *i.ID)
}
}
}View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the VMSS with `az vmss show` and confirm the ipConfigurations[].subnet.id is a full ARM subnet ID; if not, fix the scale set (recreate or update it via kops/az).
- If seen in tests, populate Subnet.ID in the mock VirtualMachineScaleSetIPConfiguration fixture.
- Verify the Azure SDK (azure-sdk-for-go compute package) version pinned in go.mod matches the one kOps was built against; upgrade/downgrade and run `make gomod`.
- Ensure the scale set was provisioned by kops and not manually edited; re-run `kops update cluster` to reconcile.
Example fix
// before (test fixture / malformed resource)
Subnet: &compute.APIEntityReference{},
// after
Subnet: &compute.APIEntityReference{ID: to.Ptr("/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>")}, Defensive patterns
Strategy: validation
Validate before calling
func validateVMSSSubnetID(vmss *compute.VirtualMachineScaleSet) error {
ip := vmss.Properties.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].Properties.IPConfigurations[0]
if ip.Properties == nil || ip.Properties.Subnet == nil || ip.Properties.Subnet.ID == nil {
return fmt.Errorf("VMSS %s has no subnet ID", *vmss.Name)
}
return nil
} Type guard
func hasSubnetID(ip *compute.VirtualMachineScaleSetIPConfiguration) bool {
return ip != nil && ip.Properties != nil && ip.Properties.Subnet != nil && ip.Properties.Subnet.ID != nil
} Prevention
- Always provision VMSS through kops so subnet IDs are fully populated
- Keep the azure-sdk-for-go compute package pinned and tested with kops
- Populate full ARM subnet IDs in any custom ARM/Bicep templates
- Add fixtures with complete subnet IDs in tests
When it happens
Trigger: Find() on a VMSS whose networkInterfaceConfigurations[0].properties.ipConfigurations[0].properties.subnet exists but has subnet.id == nil — i.e. an Azure API/SDK response where the Subnet subresource is present but its ARM resource ID was not populated.
Common situations: Hand-crafted or mocked Azure responses in tests that set the subnet object but forget its ID; scale sets created or modified outside kOps with an incomplete IP configuration; Azure SDK version changes that alter how subresource IDs are returned.
Related errors
- found VMSS without ID
- expected exactly one subnet for InstanceGroup %q; subnets wa
- unexpected subnet type: for InstanceGroup %q; type was %s
- instance group must have the same min and max size in Azure,
- malformed format of image urn: %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4dde83b04f1417e6.
Report an issue: GitHub.