{"record":{"id":"7fcb5eea90e8fc6f","repo":"microsoft/aspire","slug":"could-not-resolve-subnet-id-for-agc-load-balancer-lb-name","errorCode":null,"errorMessage":"Could not resolve subnet ID for AGC load balancer '{lb.Name}'.","messagePattern":"Could not resolve subnet ID for AGC load balancer '(.+?)'\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentResource.AksPipeline.cs","lineNumber":543,"sourceCode":"                if (lb.DisplacedDelegationServiceName is { } displaced)\n                {\n                    // The subnet had an explicit non-trafficControllers service delegation when\n                    // AddLoadBalancer was called. AzureSubnetResource emits only the LAST\n                    // AzureSubnetServiceDelegationAnnotation, so AGC's trafficControllers\n                    // delegation displaced the user's. Warn at deploy time so the user can\n                    // either remove the original delegation or use a separate subnet.\n                    context.Logger.LogWarning(\n                        \"AddLoadBalancer overrode an existing service delegation '{DisplacedServiceName}' \" +\n                        \"on the subnet for AGC load balancer '{LoadBalancerName}' with \" +\n                        \"'Microsoft.ServiceNetworking/trafficControllers'. AGC requires this delegation; \" +\n                        \"if you need '{DisplacedServiceName}' to remain, use a separate subnet for the load balancer.\",\n                        displaced, lb.Name, displaced);\n                }\n\n                var subnetId = await ((IValueProvider)lb.SubnetIdReference).GetValueAsync(context.CancellationToken).ConfigureAwait(false);\n                if (string.IsNullOrEmpty(subnetId))\n                {\n                    throw new InvalidOperationException(\n                        $\"Could not resolve subnet ID for AGC load balancer '{lb.Name}'.\");\n                }\n\n                var kubeConfigPath = KubernetesEnvironment.KubeConfigPath\n                    ?? throw new InvalidOperationException(\n                        $\"Cannot apply AGC ApplicationLoadBalancer CR for '{lb.Name}': \" +\n                        $\"kubeconfig was not set by aks-get-credentials-{Name}.\");\n\n                // Wait for the azure-alb-external GatewayClass to appear. The AGC ALB\n                // controller add-on installs it asynchronously, so polling is required\n                // even after the AKS cluster reports Succeeded. 10-minute budget matches\n                // the E2E test budget in KubernetesGatewayTlsDeploymentTests.cs.\n                await WaitForAzureAlbGatewayClassAsync(\n                    kubeConfigPath, context.Logger, TimeSpan.FromMinutes(10),\n                    context.CancellationToken).ConfigureAwait(false);\n\n                // Apply the ApplicationLoadBalancer CR via kubectl apply -f - using stdin\n                // so we don't need a temp file. JSON is a valid YAML subset for kubectl.","sourceCodeStart":525,"sourceCodeEnd":561,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentResource.AksPipeline.cs#L525-L561","documentation":"Thrown by ApplyAlbCrdAsync when the subnet ID reference configured on an AGC (Azure Gateway with Containers) load balancer resource resolves to null or empty. kubectl cannot apply the ApplicationLoadBalancer CR without a concrete subnet resource ID.","triggerScenarios":"During deploy, the pipeline calls GetValueAsync on lb.SubnetIdReference (an IValueProvider) and receives null/empty, e.g. because the referenced subnet output has not been evaluated or the reference is misconfigured.","commonSituations":"The SubnetId points to a resource whose value comes from an Azure output that failed to resolve; the load balancer was configured without a subnet or with an empty string; wiring the reference to the wrong parameter type.","solutions":["Ensure the AKS/vnet Bicep module outputs the subnet resource ID and that the reference is wired via .WithSubnetId(...) or equivalent","Verify the subnet reference points to a deployed virtual network subnet, not a name or prefix","Re-run the deploy so referenced outputs are resolved before the ALB step","Log the resolved SubnetIdReference value to confirm it is a full ARM subnet ID like /subscriptions/.../subnets/<name>"],"exampleFix":"// before\n// var alb = aks.AddAlbLoadBalancer(\"alb\"); // subnet never set\n// after\n// var alb = aks.AddAlbLoadBalancer(\"alb\").WithSubnetId(vnet, \"app-subnet\");","handlingStrategy":"validation","validationCode":"var subnetId = await ((IValueProvider)lb.SubnetIdReference).GetValueAsync(ct);\nif (string.IsNullOrWhiteSpace(subnetId) || !subnetId.StartsWith(\"/subscriptions/\"))\n    throw new InvalidOperationException($\"Subnet ID unresolved or malformed: '{subnetId}'\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wire the ALB to a deployed vnet subnet via the supported API","Assert the resolved value is a full ARM subnet ID before deploy"],"tags":["azure","aks","agc","subnet","config"],"backgroundTag":"empty-required-field","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"}