Describe the bug
On host ports below 1024, OrbStack ignores the bind address given in -p and creates the
listening socket on 0.0.0.0 instead. Above 1024 the address is honoured.
The visible consequence is that a privileged-port forward now collides with any unrelated
listener that holds the same port on a different host address. The container starts, docker ps
advertises the requested mapping, nothing is reported to the user, and no host socket exists.
This is the same specific-address/privileged-port boundary as #2567, which was closed as
"Fixed in v2.2.2". On the TCP path in v2.2.3 the failure mode has changed rather than gone:
2.2.2 fixed the silent no-socket case, but the socket that is now created is bound to the
wrong address.
To Reproduce
Host: macOS 15.7.4 (24G517), Apple Silicon (arm64), OrbStack 2.2.3, Docker Engine 29.4.0.
Unprivileged host port — bind address honoured (correct):
$ docker run --rm -d -p 127.0.0.1:8443:80 alpine sleep 25
$ docker ps --format '{{.Ports}}'
127.0.0.1:8443->80/tcp
$ netstat -an -p tcp | grep '\.8443 ' | grep LISTEN
tcp4 0 0 127.0.0.1.8443 *.* LISTEN
Privileged host port — bind address ignored, wildcard socket (wrong):
$ docker run --rm -d -p 127.0.0.1:444:80 alpine sleep 25
$ docker ps --format '{{.Ports}}'
127.0.0.1:444->80/tcp
$ netstat -an -p tcp | grep '\.444 ' | grep LISTEN
tcp4 0 0 *.444 *.* LISTEN
Both containers request 127.0.0.1, and Docker reports 127.0.0.1 for both; only the
unprivileged one actually binds it.
How this breaks a real setup. A launch daemon on this machine holds 127.0.0.2:443
(an alias on lo0). ddev publishes its router as -p 127.0.0.1:443:443 and
-p 127.0.0.1:80:80. Port 80 comes up, port 443 does not — every ddev site is reachable
over HTTP and refuses connections over HTTPS, with nothing in docker logs or the UI to
explain it. ~/.orbstack/log/vmgr.log is the only place the failure appears:
📦 scon | level=error msg="failed to add forward" container=docker error="host: listen tcp4 0.0.0.0:443: bind: address already in use"
The same substitution is visible on port 443 itself once the conflicting daemon is stopped
and the forward succeeds — the mapping asks for 127.0.0.1, the socket is on 0.0.0.0:
$ docker port ddev-router | grep 443
443/tcp -> 127.0.0.1:443
$ netstat -an -p tcp | grep '\.443 ' | grep LISTEN
tcp4 0 0 *.443 *.* LISTEN
127.0.0.1:443 was free the whole time — only 127.0.0.2:443 was taken, so the requested
forward could have been bound without any conflict. Stopping the other daemon is the only
thing that fixes it. docker.expose_ports_to_lan: false makes no difference; the socket is
still created on 0.0.0.0.
Expected behavior
-p 127.0.0.1:443:443 should bind 127.0.0.1:443 regardless of the port being privileged,
exactly as it does on 8443 — and it should not fail because an unrelated address holds the
same port number.
Secondarily: a forward that cannot be bound should surface somewhere the user can see it
(docker ps, the app UI, or an error at container start) rather than only in vmgr.log.
Related issues
Describe the bug
On host ports below 1024, OrbStack ignores the bind address given in
-pand creates thelistening socket on
0.0.0.0instead. Above 1024 the address is honoured.The visible consequence is that a privileged-port forward now collides with any unrelated
listener that holds the same port on a different host address. The container starts,
docker psadvertises the requested mapping, nothing is reported to the user, and no host socket exists.
This is the same specific-address/privileged-port boundary as #2567, which was closed as
"Fixed in v2.2.2". On the TCP path in v2.2.3 the failure mode has changed rather than gone:
2.2.2 fixed the silent no-socket case, but the socket that is now created is bound to the
wrong address.
To Reproduce
Host: macOS 15.7.4 (24G517), Apple Silicon (arm64), OrbStack 2.2.3, Docker Engine 29.4.0.
Unprivileged host port — bind address honoured (correct):
Privileged host port — bind address ignored, wildcard socket (wrong):
Both containers request
127.0.0.1, and Docker reports127.0.0.1for both; only theunprivileged one actually binds it.
How this breaks a real setup. A launch daemon on this machine holds
127.0.0.2:443(an alias on
lo0). ddev publishes its router as-p 127.0.0.1:443:443and-p 127.0.0.1:80:80. Port 80 comes up, port 443 does not — every ddev site is reachableover HTTP and refuses connections over HTTPS, with nothing in
docker logsor the UI toexplain it.
~/.orbstack/log/vmgr.logis the only place the failure appears:The same substitution is visible on port 443 itself once the conflicting daemon is stopped
and the forward succeeds — the mapping asks for
127.0.0.1, the socket is on0.0.0.0:127.0.0.1:443was free the whole time — only127.0.0.2:443was taken, so the requestedforward could have been bound without any conflict. Stopping the other daemon is the only
thing that fixes it.
docker.expose_ports_to_lan: falsemakes no difference; the socket isstill created on
0.0.0.0.Expected behavior
-p 127.0.0.1:443:443should bind127.0.0.1:443regardless of the port being privileged,exactly as it does on 8443 — and it should not fail because an unrelated address holds the
same port number.
Secondarily: a forward that cannot be bound should surface somewhere the user can see it
(
docker ps, the app UI, or an error at container start) rather than only invmgr.log.Related issues
case above still misbehaves in v2.2.3, in a different way.
EACCES), still open.listen tcp 0.0.0.0:<port>: bind: address already in usesymptom, there causedby a macOS service holding the port. That report is about the retry loop and log spam; this
one is about the bind address being wrong in the first place.
lo0-alias port mappings not working.127.0.0.1forwards (connection reset).