Skip to content

[Bug] Containers: ports below 1024 fail on localhost with a misleading "port is already allocated" error #68

Open

Description

@tommyent

Description

In VMPal Containers, publishing a Mac port below 1024 on localhost fails, and the error blames a port conflict that doesn't exist. Ports of 1024 and up work, and so do low ports published on 0.0.0.0.

macOS lets unprivileged processes bind ports below 1024 only on the wildcard address (0.0.0.0 / ::), not on 127.0.0.1 / ::1. VMPal publishes -p ports on localhost, so any explicit low port fails. vmpal containers run already works around this for ports it chooses (80 → 8080), but explicit ports from docker run / Docker Compose can't be remapped. DDEV's router (80/443), Traefik and other reverse-proxy setups fail on VMPal and work on Docker Desktop and OrbStack.

Steps to Reproduce

  1. Turn on Containers.
  2. vmpal containers run -d --name a -p 81:80 nginx:alpine
  3. vmpal containers run -d --name b -p 0.0.0.0:82:80 nginx:alpine
  4. vmpal containers run -d --name c -p 8081:80 nginx:alpine

Current Behavior

  • a exits: Bind for 127.0.0.1:81 failed: port is already allocated (Permission denied). Another program or container uses that port on this Mac: publish another with -p. Nothing uses port 81 (a plain non-root bind of 0.0.0.0:81 succeeds at the same moment).
  • b (0.0.0.0:82) and c (8081) start and serve pages.
  • DDEV 1.25.4 with the vmpal docker context: ddev-router fails with Bind for 127.0.0.1:443 failed ... Permission denied.

The underlying macOS rule, outside VMPal (non-root Python bind(), port 444): 127.0.0.1 and ::1 → EACCES; 0.0.0.0 and :: → OK.

Expected Behavior

  • -p 80:80 / -p 443:443 work on localhost as they do with Docker Desktop and OrbStack (e.g. through a privileged helper), or
  • at minimum, the error says macOS refuses ports below 1024 on localhost and suggests -p 0.0.0.0:<port>:… or a port ≥ 1024, instead of reporting another program on the port.

Possibly the same cause as #67 (Mac port 443 "in use by another app" for a Windows VM's port forwarding); not verified.

Workaround for DDEV users: ddev config global --router-bind-all-interfaces, which exposes the router on the LAN.

Environment

  • App version: VMPal 0.89, Containers kernel 7.2.11
  • Mac: MacBook Air, M5, 24 GB
  • macOS version: macOS 27.2 (26B5112a)
  • VM's OS: n/a (Containers)

Activity

  1. huyphams commented on Oct 20, 2026

    @huyphams
    Contributor

    Hi @tommyent, thanks, your analysis is right: macOS lets only root listen below port 1024 on 127.0.0.1 and ::1, and VMPal’s engine called that “port is already allocated”.

    In VMPal 0.90 the error says what’s actually wrong:

    Bind for 127.0.0.1:81 failed: permission denied: macOS lets only root listen on 127.0.0.1 below port 1024. Publish a port from 1024 up, or 0.0.0.0:81, which other computers on the network can reach too.
    

    Making -p 80:80 and -p 443:443 work on localhost, as Docker Desktop and OrbStack do (DDEV’s router, Traefik), is still to do, so we’re keeping this issue open for it. Until then, a port from 1024 up, or 0.0.0.0:<port> (reachable from your network too), works.

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