Repository navigation
[Floci] Service Bus AMQP host ports race with DCP proxy allocation; broker unreachable or fails to bind #2240
Description
Describe the bug
FlociServiceBusEndpointAllocator chooses the Service Bus child's AMQP and AMQPS host ports with new TcpListener(IPAddress.Any, 0). It then calls Stop() on the listeners in a finally block. The ports are not bound again until floci-az later starts the Artemis sidecar container with -p <port>:5672.
DCP allocates the proxy ports for project resources from the same OS ephemeral range, and it does so in that window. DCP can therefore receive the port the allocator just released. In an AppHost with several projects, this happens often enough to break local runs and CI.
The result depends on the platform:
- Windows + Docker Desktop: Docker's bind on all addresses (
0.0.0.0:<port>/[::]:<port>) succeeds next to DCP's listener on127.0.0.1:<port>. A connection tolocalhost:<port>goes to the more specific DCP listener, which is a project's proxy. The broker is up but cannot be reached from the host, and AMQP clients hang until they time out. - Linux: Docker fails to start the sidecar with
Bind for 0.0.0.0:<port> failed: port is already allocated. floci-az logs an ERROR and keeps reporting healthy; that part is a separate floci-az issue.
Evidence from one aspire start --isolated run on Windows. These are the DCP Service objects (kubectl --kubeconfig <dcp kubeconfig> get services.usvc-dev.developer.microsoft.com):
| DCP Service | addressAllocationMode | Port |
|---|---|---|
floci-servicebus-amqp |
Proxyless | spec.port 51110 |
chat-https (a project) |
Localhost | effectivePort 51110 |
floci-servicebus-amqps |
Proxyless | spec.port 51111 |
email-worker (a project) |
Localhost | effectivePort 51111 |
These are the host listeners (Get-NetTCPConnection -LocalPort 51110 -State Listen):
127.0.0.1:51110 dcp
::1:51110 dcp
:::51110 com.docker.backend
From inside the sidecar, the broker answers the AMQP header on 127.0.0.1:5672, and Artemis logs Started EPOLL Acceptor at 0.0.0.0:5672 and Server is now active. From the host, the same AMQP header sent to localhost:51110 gets no reply.
In CI on Linux (GitHub Actions ubuntu-latest), every failing port we recorded was inside the Linux ephemeral range (32768-60999).
Regression
Introduced with the allocator in 13.6.0. Before that, the AppHost had to allocate these ports itself.
Steps to reproduce
- Create an AppHost with
AddFlociAzure(...).WithServiceBus()and roughly 10 or more project resources, so DCP allocates many proxy ports. - Run
aspire start --isolatedrepeatedly. - On some runs, the Service Bus port matches a project proxy's port. Compare
floci-servicebus-amqp'sspec.portwith the projects'effectivePortin the DCP Services. On Windows, AMQP clients then time out againstlocalhost:<port>. On Linux, the sidecar does not start.
Expected behavior
Two processes should never be handed the same Service Bus host port. Possible fixes:
- Select the ports outside every OS ephemeral range, for example a random free port in 20000-32767, below Linux's 32768 and Windows/macOS's 49152. A downstream AppHost now does this by passing explicit ports to
WithServiceBus(name, amqpPort, amqpTlsPort), and the problem has not recurred. - Let DCP allocate the endpoints instead of handing it a port the integration no longer holds, if Aspire allows that for a container that floci-az starts itself.
Keeping the port random keeps concurrent --isolated AppHosts working.
Screenshots
N/A
IDE and version
Other (CLI: aspire start --isolated)
IDE version
Aspire CLI / Aspire.AppHost.Sdk 13.6.1
Nuget packages
CommunityToolkit.Aspire.Hosting.Floci 13.6.0
Image: floci/floci-az:0.14.0
Docker Desktop 4.88.1 (Engine 29.7.2), Windows 11; also GitHub Actions ubuntu-latest
Additional context
On the Windows side, TcpListener(IPAddress.Any, 0) cannot detect a later conflict with a loopback-specific listener, so checking whether the port is free at selection time does not prevent this. Only the choice of port range does.
Help us help you
Yes, I'd like to be assigned to work on this item.
Activity
fix(floci): select Service Bus host ports below the ephemeral range (C…