Skip to content

egress sidecar start fails intermittently: host port probe misses OS-reserved ranges (Docker Desktop/Windows) and start failure is not retried with a new port #1702

Description

@SummerSec

Summary

When creating sandboxes with an egress sidecar, the randomly allocated host publish port can land in an OS-reserved port range that is invisible from inside the server container. Docker then fails the start with ports are not available / bind: ... forbidden by its access permissions, the whole sandbox creation returns HTTP 500, and there is no retry with a different port.

Environment

  • OpenSandbox server 0.1.11 (Docker provider), running as a container
  • Docker Desktop on Windows 11 (Linux containers) — host publish happens on the Windows host
  • Multiple sandboxes created concurrently, networkPolicy requiring an egress sidecar (each sandbox needs 2+ host ports)

Symptom

Sandbox creation intermittently fails (observed ~10–15% of concurrent batches), wrapped as:

Egress sidecar container failed to start.

Server logs (INFO/WARNING) show the real cause:

sandbox=44bee438-… | action=start egress sidecar | error=500 Server Error for http+docker://localhost/v1.55/containers/4e54dce2…/start:
Internal Server Error ("ports are not available: exposing port TCP 0.0.0.0:49870 -> 127.0.0.1:0:
listen tcp4 0.0.0.0:49870: bind: An attempt was made to access a socket in a way forbidden by its access permissions.")

On this host, netsh interface ipv4 show excludedportrange protocol=tcp shows Hyper-V/WinNAT reserved ranges such as 49845–49944, 50060–50359 — and the failing ports (49870, 50103 on two different attempts) both fell exactly inside those ranges. Retrying the same request succeeds.

Root cause

  1. allocate_host_port() in server/opensandbox_server/services/docker/port_allocator.py probes availability with socket.bind() inside the server container (Linux network stack). On Docker Desktop/Windows the actual bind happens on the Windows host during docker start, where OS-reserved excluded port ranges make the bind fail with WSAEACCES — the container-side probe cannot see this.
  2. _start_egress_sidecar() in networking.py only retries when the failure is the IPv6-sysctl rejection; any other start failure (including ports are not available) cleans up and raises HTTP 500 without re-allocating a new host port.

Suggested fix

  • On docker start failure with a port-publish error (ports are not available, bind: permission errors), re-allocate a different host port and retry the create/start once or twice before giving up — port conflicts are probabilistic on hosts with dynamic reserved ranges.
  • Longer term: make the probe Docker-publish-aware (or allow configuring the host port pool so it can be kept clear of reserved ranges).
  • Consider surfacing the original Docker error instead of only the generic message, so callers can distinguish port conflicts from other start failures.

Additional context

Host port allocation range is 40000–60000 (allocate_host_port defaults); OS-reserved ranges on Windows change between reboots, which is why the failure is intermittent and environment-dependent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions