WSL2 Ubuntu 24.04: Restrictive Ephemeral Port Range Breaks Docker Container Orchestration
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 33.7k
- Forks
- 1.8k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 116
Description
### Windows Version
10.0.26100.6899
### WSL Version
2.6.1.0
### Are you using WSL 1 or WSL 2?
- [x] WSL 2
- [ ] WSL 1
### Kernel Version
6.6.87.2-1
### Distro Version
Ubuntu 24.04
### Other Software
_No response_
### Repro Steps
1. Install Docker Desktop with WSL2 backend on Windows
2. Install/use Ubuntu 24.04 LTS distribution in WSL2
3. Open Ubuntu WSL2 terminal and check the ephemeral port range:
```bash
cat /proc/sys/net/ipv4/ip_local_port_range
```
**Observe:** Output shows `44620 48715` (only 4,096 ports)
**Expected:** Should show `32768 60999` (standard Linux default: 28,232 ports)
4. Attempt to spawn multiple Docker containers with dynamic port allocation:
```bash
# Try spawning containers with random host ports
for i in {1..10}; do
docker run -d --rm -p 0.0.0.0:0:80 nginx
done
```
5. Observe errors like:
```
docker: Error response from daemon: ports are not available:
exposing port TCP 0.0.0.0:48185 -> 127.0.0.1:0: listen tcp 0.0.0.0:48185:
bind: Only one usage of each socket address (protocol/network address/port)
is normally permitted.
```
6. Note that all failed port numbers fall within the restricted range (44620-48715)
7. Verify minimal system load:
```bash
# Check active connections in ephemeral range
ss -tan | awk '{print $4}' | grep -oE ':[0-9]+$' | grep -oE '[0-9]+' | awk '$1 >= 44620 && $1 <= 48715' | wc -l
# Output: ~8 connections (minimal load)
# Check running containers
docker ps | wc -l
# Output: 1-2 containers (minimal load)
```
**Result:** Docker fails to allocate ports despite minimal system activity, proving the range is too restrictive.
### Expected Behavior
WSL2 should use the **standard Linux ephemeral port range (32768-60999)** to:
1. Match behavior of native Linux distributions
2. Provide sufficient ports for concurrent Docker containers
3. Avoid conflicts with Docker's dynamic port allocation mechanism (49153-65535)
4. Support enterprise CI/CD workflows and automated testing frameworks
5. Allow 10+ concurrent containers with dynamic port binding
**Reference:** Standard Linux systems (Ubuntu Server, RHEL, Debian) all default to 32768-60999 for ephemeral ports. This is documented in kernel.org and is the expected behavior for any Linux environment.
**Docker Desktop expectation:** When running Docker Desktop with WSL2 backend, users expect Docker's dynamic port allocation (`docker run -p 0:80`) to work reliably for concurrent containers, as it does on native Linux.
### Actual Behavior
WSL2 Ubuntu 24.04 uses an abnormally restrictive ephemeral port range (44620-48715) that causes:
**Port Exhaustion Under Normal Load:**
- Only 4,096 available ephemeral ports (7x smaller than standard Linux)
- Docker's dynamic port allocation consistently fails
- Automated container orchestration becomes impossible
**Real-world failure example:**
```
Building task-specific Docker image for fix-broken-deployment...
Specimen Docker image built successfully!
100%|██████████| 1/1 [00:28<00:00, 29.00s/it]
⚠ Container startup failed (attempt 1/3): Failed to start container:
docker: Error response from daemon: ports are not available:
exposing port TCP 0.0.0.0:48185 -> 127.0.0.1:0: listen tcp 0.0.0.0:48185:
bind: Only one usage of each socket address (protocol/network address/port)
is normally permitted.
Retrying with new container and port...
⚠ Container startup failed (attempt 2/3): Failed to start container:
docker: Error response from daemon: ports are not available:
exposing port TCP 0.0.0.0:47941 -> 127.0.0.1:0: listen tcp 0.0.0.0:47941:
bind: Only one usage of each socket address is normally permitted.
Retrying with new container and port...
✗ Container startup failed after 3 attempts: Failed to start container:
docker: Error response from daemon: ports are not available:
exposing port TCP 0.0.0.0:46025 -> 127.0.0.1:0: listen tcp 0.0.0.0:46025:
bind: Only one usage of each socket address is normally permitted.
Task failed with exception: Failed to start container [...]
```
**Pattern observed:** All attempted ports (48185, 47941, 46025, 45239, 45511, 45075, 46217, 44641, 46353, 46907, 45377) fall within the 44620-48715 range and fail consistently.
**Impact on workflows:**
- ✗ Automated testing frameworks fail (e.g., apex-arena with 10 concurrent evaluation runs)
- ✗ CI/CD pipelines cannot spawn parallel containers
- ✗ Docker Compose with multiple services experiences random failures
- ✗ Development workflows with microservices break intermittently
- ✗ Kubernetes testing in WSL2 becomes unreliable
**System state at failure:**
```bash
$ cat /proc/sys/net/ipv4/ip_local_port_range
44620 48715
$ ss -tan | awk '{print $4}' | grep -oE ':[0-9]+$' | grep -oE '[0-9]+' | awk '$1 >= 44620 && $1 <= 48715' | wc -l
8 # Only 8 active connections
$ docker ps | wc -l
1 # Only 1 running container
# Yet Docker cannot allocate ports - the range is simply too small
```
**Workaround that confirms root cause:**
```bash
# Expanding to standard Linux range immediately resolves the issue
echo "net.ipv4.ip_local_port_range = 32768 60999" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# After fix: Docker containers spawn successfully
$ for i in {1..10}; do docker run -d --rm -p 0:80 nginx; done
# All 10 containers start successfully ✓
```
This proves the issue is WSL2's non-standard ephemeral port configuration, not Docker or user error.
### Diagnostic Logs
**Ephemeral Port Range (Before Fix):**
```bash
$ cat /proc/sys/net/ipv4/ip_local_port_range
44620 48715
```
**Active Connections in Ephemeral Range:**
```bash
$ ss -tan | awk '{print $4}' | grep -oE ':[0-9]+$' | grep -oE '[0-9]+' | sort -n | awk '$1 >= 44620 && $1 <= 48715'
45487
45487
45487
45669
46824
47114
47120
47392
# Total active: 8 connections
```
**Docker Containers:**
```bash
$ docker ps -a --format "table {{.ID}} {{.Image}} {{.Status}} {{.Ports}}"
CONTAINER ID IMAGE STATUS PORTS
3f7beeaec544 nebula-devops Up 59 minutes 0.0.0.0:80->80/tcp, [...], 0.0.0.0:6443->6443/tcp
# Only 1 container running, minimal port usage
```
**TIME-WAIT Connections:**
```bash
$ ss -tan state time-wait | wc -l
1 # Minimal TIME-WAIT state
```
**Attempted Port Allocations (from error logs):**
All these ports failed to bind:
- 48185, 47941, 46025 (first task, 3 attempts)
- 45239, 45511, 45075 (second task, 3 attempts)
- 46217, 44641, 46353 (third task, 3 attempts)
- 46907, 45377, ... (fourth task, attempts)
**All ports fall within the restricted range 44620-48715.**
**Successful Fix Verification:**
```bash
# After applying workaround
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999 # Standard Linux range
# Docker now works reliably
$ docker run -d --rm -p 0:80 nginx
# Success ✓
```
**Related Issue:**
This appears related to #12228 which documents the same restrictive port range causing conflicts with Windows applications. The issue affects Docker Desktop users specifically when using dynamic port allocation.
**Request:** Please update WSL2's default ephemeral port range to match standard Linux distributions (32768-60999) to ensure compatibility with Docker Desktop and modern containerized development workflows.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported range with `cat /proc/sys/net/ipv4/ip_local_port_range` in Ubuntu 24.04 on WSL2, then run the Docker dynamic-port loop from the issue. Read related issue #12228 and investigate where WSL2 establishes the default networking configuration. Done means the default range is confirmed or corrected and concurrent `docker run -p 0:80` containers succeed without the workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, linux, ubuntu
- Domain
- devops, networking, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100