{"record":{"id":"7bf7736417d2e2d2","repo":"microsoft/aspire","slug":"could-not-generate-a-unique-name-for-security-rule-basename","errorCode":null,"errorMessage":"Could not generate a unique name for security rule '{baseName}'","messagePattern":"Could not generate a unique name for security rule '(.+?)'","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs","lineNumber":673,"sourceCode":"        }\n\n        nsgResource.SecurityRules.Add(rule);\n\n        return builder;\n    }\n\n    private static string GenerateUniqueRuleName(AzureNetworkSecurityGroupResource nsgResource, string access, string direction, string? port, string? from, string? to)\n    {\n        var baseName = GenerateRuleName(access, direction, port, from, to);\n\n        // Check for conflicts and append an index if needed\n        var candidateName = baseName;\n        var index = 2;\n        while (nsgResource.SecurityRules.Any(r => r.Name == candidateName))\n        {\n            if (index == 100)\n            {\n                throw new InvalidOperationException($\"Could not generate a unique name for security rule '{baseName}'\");\n            }\n            candidateName = $\"{baseName}-{index}\";\n            index++;\n        }\n\n        return candidateName;\n    }\n\n    private static string GenerateRuleName(string access, string direction, string? port, string? from, string? to)\n    {\n        var parts = new List<string> { access, direction };\n\n        if (port is not null)\n        {\n            parts.Add(port);\n        }\n\n        if (from is not null)","sourceCodeStart":655,"sourceCodeEnd":691,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs#L655-L691","documentation":"When a shorthand rule is added, the NSG generates a unique rule name by appending -2, -3, ... to the base name, scanning existing rule names. If even 'baseName-99' collides (i.e., 99 candidates already exist), it gives up and throws InvalidOperationException rather than looping forever.","triggerScenarios":"Adding ~100 or more rules to a single NSG sharing the same base rule name, so every suffixed candidate 'base-2'...'base-99' already exists in nsgResource.SecurityRules.","commonSituations":"Programmatically generating many per-IP or per-port rules with identical base names in a loop; a bug causing the same rule to be added repeatedly; extremely large NSGs near Azure's rule limits.","solutions":["Give each rule a distinct, descriptive base name instead of reusing one base for many rules.","Reduce the number of rules by consolidating (use CIDR ranges or port ranges instead of many single rules).","Check for accidental loops that add the same rule many times; the NSG likely contains duplicates to clean up.","If needed, catch InvalidOperationException and pick explicit unique names yourself."],"exampleFix":"// before\nfor (var i = 0; i < 150; i++)\n    nsg.AllowInbound(\"allow-app\", 8000 + i); // base name reused 150x\n\n// after\nfor (var i = 0; i < 150; i++)\n    nsg.AllowInbound($\"allow-app-{i}\", 8000 + i);","handlingStrategy":"try-catch","validationCode":"int collisions = nsg.Resource.SecurityRules.Count(r => r.Name.StartsWith(baseName));\nif (collisions >= 99) { /* choose explicit unique names instead of relying on suffixing */ }","typeGuard":null,"tryCatchPattern":"try { nsg.AllowInbound(baseName, port); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Could not generate a unique name\")) { /* pass a fully unique rule name explicitly */ }","preventionTips":["Give each security rule a unique, descriptive base name — don't reuse one name for many rules.","Consolidate rules with CIDR/port ranges instead of generating hundreds of similar rules.","Watch for accidental loops that repeatedly add rules with the same name."],"tags":["azure","networking","nsg","name-generation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}