kubernetes/kops · error

malformed format of NetworkSecurityGroup ID: %s, %d

Error message

malformed format of NetworkSecurityGroup ID: %s, %d

What it means

ParseNetworkSecurityGroupID parses an Azure NSG resource ID of the form /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/networkSecurityGroups/<nsg> (9 slash-separated parts). If the split count differs, the ID is malformed and this error is returned with the observed count. It guards against malformed identifiers before constructing the NetworkSecurityGroupID struct.

Source

Thrown at upup/pkg/fi/cloudup/azure/azure_utils.go:94

type NetworkSecurityGroupID struct {
	SubscriptionID           string
	ResourceGroupName        string
	NetworkSecurityGroupName string
}

// String returns the NetworkSecurityGroup ID in the path format.
func (s *NetworkSecurityGroupID) String() string {
	return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s",
		s.SubscriptionID,
		s.ResourceGroupName,
		s.NetworkSecurityGroupName)
}

// ParseNetworkSecurityGroupID parses a given NetworkSecurityGroup ID string and returns a NetworkSecurityGroup ID.
func ParseNetworkSecurityGroupID(s string) (*NetworkSecurityGroupID, error) {
	l := strings.Split(s, "/")
	if len(l) != 9 {
		return nil, fmt.Errorf("malformed format of NetworkSecurityGroup ID: %s, %d", s, len(l))
	}
	return &NetworkSecurityGroupID{
		SubscriptionID:           l[2],
		ResourceGroupName:        l[4],
		NetworkSecurityGroupName: l[8],
	}, nil
}

// ApplicationSecurityGroupID contains the resource ID/names required to construct a ApplicationSecurityGroup ID.
type ApplicationSecurityGroupID struct {
	SubscriptionID               string
	ResourceGroupName            string
	ApplicationSecurityGroupName string
}

// String returns the ApplicationSecurityGroup ID in the path format.
func (s *ApplicationSecurityGroupID) String() string {
	return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/applicationSecurityGroups/%s",

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Provide the complete ID: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/networkSecurityGroups/<nsg-name>.
  2. Get the exact ID with `az network nsg show -g <rg> -n <nsg> --query id`.
  3. Check the slash-segment count is 9 before passing it in.
  4. Ensure the NSG name itself contains no "/" (would change the count); rename if necessary.
  5. Fix the referencing field in the cluster spec and re-run kops update cluster.

Example fix

// before
nsgID = "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/networkSecurityGroups"
// after
nsgID = "/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/networkSecurityGroups/my-nsg"
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate NSG ID shape before parsing
func looksLikeAzureNSGID(s string) bool {
    l := strings.Split(s, "/")
    return len(l) == 9 &&
        l[1] == "subscriptions" &&
        l[3] == "resourcegroups" &&
        l[7] == "networkSecurityGroups"
}
if !looksLikeAzureNSGID(nsgID) {
    return fmt.Errorf("expected full NSG resource ID, got %q", nsgID)
}

Type guard

func isNSGID(s string) bool {
    return strings.HasPrefix(s, "/subscriptions/") &&
        strings.Contains(s, "networkSecurityGroups/") &&
        strings.Count(s, "/") == 8
}

Try / catch

parsed, err := azure.ParseNetworkSecurityGroupID(nsgID)
if err != nil {
    log.Printf("NSG ID %q malformed (%v); expected /subscriptions/.../networkSecurityGroups/<name>", nsgID, err)
    return err
}

Prevention

When it happens

Trigger: Calling ParseNetworkSecurityGroupID with a truncated ID, a plain NSG name, or an ID of another resource type — e.g. "/subscriptions/x/resourceGroups/rg/providers/Microsoft.Network/networkSecurityGroups" (8 parts, missing the name) or a subnet ID (11 parts).

Common situations: Pasting a truncated ID from the portal (dropping the NSG name); mixing up NSG and subnet/load balancer IDs in cluster spec fields; templating errors that cut the path; IDs copied from CLI output that was truncated by terminal width.

Understand the failure class

Related errors


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