microsoft / microsoft/WSL

WSL2 Ubuntu 24.04: Restrictive Ephemeral Port Range Breaks Docker Container Orchestration

Open
#13,696 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

network
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.