kubernetes/kops · error

malformed format of subnet ID: %s, %d

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.

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)

Solutions

  1. Use the full subnet resource ID: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>.
  2. Fetch the canonical ID via `az network vnet subnet show ... --query id` and paste that value.
  3. Verify the count of path segments matches 11 (leading empty segment from the initial slash counts).
  4. Run the TestSubnetIDParse-style check manually: strings.Split(id, "/") length must equal 11.
  5. 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

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

Related errors


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