{"record":{"id":"12742cbdd409501e","repo":"microsoft/aspire","slug":"the-default-allocatedendpoint-s-network-id-must-match-the","errorCode":null,"errorMessage":"The default AllocatedEndpoint's network ID must match the EndpointAnnotation network ID ('{_networkId}'). The attempted AllocatedEndpoint belongs to '{value.NetworkID}'.","messagePattern":"The default AllocatedEndpoint's network ID must match the EndpointAnnotation network ID \\('(.+?)'\\)\\. The attempted AllocatedEndpoint belongs to '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/EndpointAnnotation.cs","lineNumber":373,"sourceCode":"            }\n\n            // This looks bad *BUT* we check if the value is set before resolving.\n            // This preserves the semantics that if the value is not set, we return null to\n            // the caller.\n            return AllocatedEndpointSnapshot.GetValueAsync().GetAwaiter().GetResult();\n        }\n        set\n        {\n            if (value is null)\n            {\n                // Setting null will proactively set an exception on the snapshot.\n                AllocatedEndpointSnapshot.SetException(new InvalidOperationException($\"The endpoint `{Name}` is not allocated\"));\n            }\n            else\n            {\n                if (_networkId != value.NetworkID)\n                {\n                    throw new InvalidOperationException($\"The default AllocatedEndpoint's network ID must match the EndpointAnnotation network ID ('{_networkId}'). The attempted AllocatedEndpoint belongs to '{value.NetworkID}'.\");\n                }\n                AllocatedEndpointSnapshot.SetValue(value);\n            }\n        }\n#pragma warning restore CS0618 // Type or member is obsolete\n    }\n\n    /// <summary>\n    /// Gets the <see cref=\"AllocatedEndpointSnapshot\"/> for the default <see cref=\"AllocatedEndpoint\"/>.\n    /// </summary>\n    [Obsolete(\"This property will be marked as internal in future Aspire release. Use AllocatedEndpoint and AllAllocatedEndpoints properties to access and change allocated endpoints associated with an EndpointAnnotation.\")]\n    public ValueSnapshot<AllocatedEndpoint> AllocatedEndpointSnapshot { get; } = new();\n\n    /// <summary>\n    /// Gets the list of all AllocatedEndpoints associated with this Endpoint.\n    /// </summary>\n    public NetworkEndpointSnapshotList AllAllocatedEndpoints { get; } = new();\n}","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/EndpointAnnotation.cs#L355-L391","documentation":"EndpointAnnotation's AllocatedEndpoint property (default network slot) validates that any allocated endpoint assigned belongs to the same network as the annotation's own network ID. When the networks differ it throws an InvalidOperationException describing both IDs. This guards an internal invariant so consumers reading AllocatedEndpoint always get an endpoint consistent with the annotation's network.","triggerScenarios":"Setting annotation.AllocatedEndpoint = endpoint where endpoint.NetworkID differs from the annotation's _networkId — e.g. reusing an AllocatedEndpoint resolved for a second network configuration, or copying endpoints across annotations for different networks.","commonSituations":"Custom orchestrators or test fakes that allocate endpoints for multiple networks and assign the wrong one; caching AllocatedEndpoints by name only and reassigning them after a network switch; refactoring that split networks but kept a single assignment path.","solutions":["Use AddOrUpdateAllocatedEndpoint(networkId, endpoint) with the matching NetworkIdentifier instead of the default setter.","Ensure the endpoint was allocated for the same network as the annotation before assigning.","Create a fresh AllocatedEndpoint with the correct NetworkID rather than reusing another network's instance."],"exampleFix":"// before\nannotation.AllocatedEndpoint = allocatedForOtherNetwork; // NetworkID mismatch\n// after\nif (allocated.NetworkID == annotation.NetworkId)\n    annotation.AllocatedEndpoint = allocated;\nelse\n    annotation.AddOrUpdateAllocatedEndpoint(networkId, allocatedForThisNetwork);","handlingStrategy":"validation","validationCode":"if (allocated.NetworkID != annotation.NetworkId)\n    throw new InvalidOperationException($\"Endpoint '{allocated.EndpointsString}' belongs to network '{allocated.NetworkID}', not '{annotation.NetworkId}'.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    annotation.AllocatedEndpoint = allocated;\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"network ID must match\"))\n{\n    logger.LogError(ex, \"Network mismatch assigning endpoint {Name}: {Message}\", annotation.Name, ex.Message);\n    throw;\n}","preventionTips":["Prefer AddOrUpdateAllocatedEndpoint with an explicit NetworkIdentifier over the default AllocatedEndpoint setter.","Carry the NetworkIdentifier alongside AllocatedEndpoint instances instead of caching endpoints by name only.","Re-resolve endpoints whenever the active network changes rather than reassigning old ones.","In tests, construct AllocatedEndpoints from the same NetworkIdentifier used for the annotation."],"tags":["dotnet","aspire","networking","endpoints"],"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"}