kubernetes/kops · error
malformed format of subnet ID
Error message
malformed format of subnet ID: %s, %d
What it means
ParseSubnetID parses an Azure subnet resource ID of the form /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet> (11 slash-separated parts). If the split yields a different number of parts, the ID is malformed and this error is returned with the actual segment count. Returned to callers like the subnet task's Find and unit tests.
Solutions
- Use the full subnet resource ID: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>.
- Fetch the canonical ID via `az network vnet subnet show ... --query id` and paste that value.
- Verify the count of path segments matches 11 (leading empty segment from the initial slash counts).
- Run the TestSubnetIDParse-style check manually: strings.Split(id, "/") length must equal 11.
- Correct the subnetID field in the cluster/instance-group spec and re-run kops update.
Example fix
// before subnetID = "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet" // after subnetID = "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mysubnet"
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate subnet ID shape before parsing
func looksLikeAzureSubnetID(s string) bool {
l := strings.Split(s, "/")
return len(l) == 11 &&
l[1] == "subscriptions" &&
l[3] == "resourcegroups" &&
l[7] == "virtualNetworks" &&
l[9] == "subnets"
}
if !looksLikeAzureSubnetID(subnetID) {
return fmt.Errorf("expected full subnet resource ID, got %q", subnetID)
} Type guard
func isSubnetID(s string) bool {
return strings.HasPrefix(s, "/subscriptions/") && strings.Count(s, "/") == 10
} Try / catch
parsed, err := azure.ParseSubnetID(subnetID)
if err != nil {
log.Printf("subnet ID %q malformed (%v); use full /subscriptions/.../subnets/<name> path", subnetID, err)
return err
} Prevention
- Copy resource IDs with az network vnet subnet show --query id, not from hand-typed paths.
- Don't paste vNet IDs where subnet IDs are expected.
- Avoid truncation when copying from terminal output.
- Store canonical Azure IDs in spec/automation variables.
- Validate ID segment counts in CI before applying specs.
When it happens
Trigger: Calling ParseSubnetID with a truncated or non-subnet Azure ID string, or a name instead of a full resource ID — e.g. "/subscriptions/x/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet" (9 parts) or "mySubnet" (1 part).
Common situations: Hand-edited cluster spec with a partial subnet path; copying a vNet ID instead of the subnet ID from the Azure portal; wrong casing/providers section missing causing a different segment count; IDs from a different Azure resource type pasted into subnet fields.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse subnet ID
- invalid Azure zone
- malformed format of loadbalancer ID
- malformed format of NetworkSecurityGroup ID
- malformed format of PublicIPAddress ID
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c4a3d764256670f1.
Report an issue: GitHub.
Appendix: source
Thrown at upup/pkg/fi/cloudup/azure/azure_utils.go:65
ResourceGroupName string
VirtualNetworkName string
SubnetName string
}
// String returns the subnet ID in the path format.
func (s *SubnetID) String() string {
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s",
s.SubscriptionID,
s.ResourceGroupName,
s.VirtualNetworkName,
s.SubnetName)
}
// ParseSubnetID parses a given subnet ID string and returns a SubnetID.
func ParseSubnetID(s string) (*SubnetID, error) {
l := strings.Split(s, "/")
if len(l) != 11 {
return nil, fmt.Errorf("malformed format of subnet ID: %s, %d", s, len(l))
}
return &SubnetID{
SubscriptionID: l[2],
ResourceGroupName: l[4],
VirtualNetworkName: l[8],
SubnetName: l[10],
}, nil
}
// NetworkSecurityGroupID contains the resource ID/names required to construct a NetworkSecurityGroup ID.
type NetworkSecurityGroupID struct {
SubscriptionID string
ResourceGroupName string
NetworkSecurityGroupName string
}
// String returns the NetworkSecurityGroup ID in the path format.
func (s *NetworkSecurityGroupID) String() string {View on GitHub (pinned to 4c8573c808)