BeyondDimension/SteamTools · error · ApplicationException
Failed to get available ports. There are no available ports.
Error message
Failed to get available ports. There are no available ports.
What it means
Thrown by GetAvailablePort after scanning every port from minPort up to IPEndPoint.MaxPort (65535) without finding one that satisfies the availability predicate (TCP-only, UDP-only, or TCP+UDP). It indicates total port exhaustion across the scanned range rather than a single collision.
Source
Thrown at src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Models/Abstractions/IReverseProxyConfig.GlobalListener.cs:114
public static int GetAvailableUdpPort(int minPort) => GetAvailablePort(IsAvailableUdp, minPort);
/// <summary>
/// 获取一个随机的可用的 TCP 和 UDP 端口
/// </summary>
/// <param name="minPort"></param>
/// <returns></returns>
public static int GetAvailableTcpAndUdpPort(int minPort) => GetAvailablePort(IsAvailableTcpAndUdp, minPort);
static int GetAvailablePort(Func<int, bool> isAvailable, int minPort)
{
for (var port = minPort; port < IPEndPoint.MaxPort; port++)
{
if (isAvailable(port) == true)
{
return port;
}
}
throw new ApplicationException("Failed to get available ports. There are no available ports.");
}
}View on GitHub (pinned to c16ffa08e0)
Solutions
- Lower minPort in the reverse-proxy config so the scan covers a wider range.
- Identify and close the process/socket leak consuming ports (check open handle counts and TIME_WAIT sockets).
- Increase the dynamic port range / reduce TIME_WAIT retention at the OS level, then retry.
- Restart the host to release leaked sockets if a process leak is confirmed.
Example fix
// before: tiny scan window var port = IReverseProxyConfig.GetAvailableTcpAndUdpPort(minPort: 65000); // after: reasonable scan window var port = IReverseProxyConfig.GetAvailableTcpAndUdpPort(minPort: 10000);
Defensive patterns
Strategy: validation
Validate before calling
// Sanity-check minPort before scanning so the range is not uselessly small.
if (minPort < IPEndPoint.MinPort || minPort > IPEndPoint.MaxPort - 1024)
throw new ArgumentOutOfRangeException(nameof(minPort), "minPort leaves too small a scan window.");
// Optionally check system ephemeral-port health before requesting a port.
var used = QueryCurrentOpenPortCount();
if (used > 50000) throw new InvalidOperationException("System near port exhaustion; free sockets first."); Try / catch
try { return IReverseProxyConfig.GetAvailableTcpAndUdpPort(minPort); }
catch (ApplicationException ex) when (ex.Message.Contains("no available ports"))
{
Log.Error("Port exhaustion in range. Consider lowering minPort or restarting the host.");
throw;
} Prevention
- Set minPort to a sensible default (e.g. 10000) so the scan has a large window.
- Monitor open socket / TIME_WAIT counts and alert before exhaustion.
- Fix socket leaks (always Dispose sockets/HttpClients; avoid creating per-request clients).
- Tune the OS dynamic port range and TIME_WAIT timeout on hosts running the proxy.
When it happens
Trigger: Calling GetAvailableTcpPort/GetAvailableUdpPort/GetAvailableTcpAndUdpPort with a minPort so high, or a system so loaded, that no port in [minPort, 65535] passes the isAvailable check.
Common situations: minPort is misconfigured to a value near 65535 leaving almost no scan range; ephemeral port exhaustion from many short-lived connections has consumed the dynamic range; a leak keeps opening sockets without closing them; security software reserves wide port ranges.
Related errors
- TCP port {httpProxyPort} is already occupied by other proces
- 5
- Could not install certificate as it is null or empty.
- Could not find any IP that can be successfully connected.
- Unable to connect to {host}
AI-assisted analysis of BeyondDimension/SteamTools@c16ffa08e0 (2026-08-13).
Data as JSON: /api/errors/e914e78548b3944b.
Report an issue: GitHub.