floci-io/floci · error · RuntimeException
No free port available in range ${basePort}-${maxPort}
Error message
No free port available in range ${basePort}-${maxPort} What it means
Thrown by docker PortAllocator.allocate when every port in [basePort, maxPort] is either already in the reserved set or fails the isPortFree probe (a ServerSocket bind). Used to pick host ports for containers (e.g. Lambda, RDS, ElastiCache, EC2 port forwards). The reserved set is per-allocator, in-memory state.
Source
Thrown at src/main/java/io/github/hectorvent/floci/core/common/docker/PortAllocator.java:43
/**
* Atomically finds and reserves a free TCP port within the specified range.
* The port is held in-memory until {@link #release(int)} is called, preventing
* concurrent callers from picking the same port before Docker binds it.
*
* @param basePort the lowest port number to try (inclusive)
* @param maxPort the highest port number to try (inclusive)
* @return a reserved free port within the range
* @throws RuntimeException if no free port is available in the range
*/
public synchronized int allocate(int basePort, int maxPort) {
for (int port = basePort; port <= maxPort; port++) {
if (!reserved.contains(port) && isPortFree(port)) {
reserved.add(port);
LOG.debugv("Allocated port {0} from range {1}-{2}", String.valueOf(port), String.valueOf(basePort), String.valueOf(maxPort));
return port;
}
}
throw new RuntimeException("No free port available in range " + basePort + "-" + maxPort);
}
/**
* Marks a port as reserved without probing whether it is free. Used on restart to
* re-reserve host ports already held by surviving containers (e.g. persisted EC2
* port forwards) so the allocator does not hand them out again.
*/
public synchronized void markReserved(int port) {
reserved.add(port);
}
/**
* Releases a previously allocated port back to the pool.
* Should be called when the Docker container that was using the port is removed.
*/
public void release(int port) {
if (reserved.remove(port)) {
LOG.debugv("Released port {0}", String.valueOf(port));View on GitHub (pinned to 62ff490619)
Solutions
- Widen the configured port range in floci config (raise max-port / lower base-port)
- Free host ports: stop conflicting processes, and clean up orphaned floci containers (docker ps, then remove)
- Restart floci so the allocator's reserved set is rebuilt from actual container state
- Run fewer concurrent docker-backed resources per emulator instance
Example fix
# before floci.port-ranges.container.base: 20000 floci.port-ranges.container.max: 20010 # after floci.port-ranges.container.base: 20000 floci.port-ranges.container.max: 21000
Defensive patterns
Strategy: fallback
Validate before calling
// before launching many containers, sanity-check headroom
int freePorts = countFreeInRange(basePort, maxPort); // probe with ServerSocket binds
if (freePorts < needed) throw new IllegalStateException("port range too small: widen config"); Try / catch
try {
return allocator.allocate(base, max);
} catch (RuntimeException e) {
// range exhausted: widen range in config or free ports, then restart; do not spin-retry
} Prevention
- Size the port range at least as large as your peak concurrent container count
- Clean up orphaned containers between test runs
- Avoid overlapping floci's ranges with well-known host service ports
When it happens
Trigger: Launching enough docker-backed resources that the configured port range (e.g. floci port-range config) is exhausted; ports already bound by other host processes; ports re-reserved on restart via markReserved for surviving containers shrinking the usable pool.
Common situations: Running many concurrent emulated resources in tests; a narrow configured port range; orphaned containers from a previous run still holding ports; other services (databases, dev servers) occupying the same range.
Related errors
- No free ports in range " + basePort + "-" + maxPort
- floci.storage.efs owner-uid and owner-gid must be set togeth
- floci.storage.efs root-permissions must be 3-4 octal digits
- Could not find a free port
- shared-volume init for ${volumeName} exited with status ${st
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/4acd5b60a689f224.
Report an issue: GitHub.