UDP ports on MacOS

I am running Docker Desktop 4.39.0 with Engine 28.0.1 on MacOS 15.3.2. I see a lot of posts related to UDP configuration but most are not answered. I have seen old posts on GitHub that are closed. Here’s the issue. I can send UDP traffic from the host MacOS into the linux container, but I can’t send UDP packets back the other way from the container to the host. To test this, I created a basic debian container with ports mapped like this --network=bridge -p 5761:5762 -p 5501:5501 -p 14551:14550/udp. After starting up the container, TCP connections on 5761 and 5501 work just fine.

To test the UDP traffic, I run tcpdump on the host like this sudo tcpdump -i any udp port 14551 and I run iperf in the container like this iperf -c 127.0.0.1 -u -p 14550. The container will generate packets, but they are not received on the host.

If I switch it around and run tcpdump on the continer at port 14550 and iperf on the host at port 14551, the UDP packets will display inside the container.

I have tried using localhost, 0.0.0.0, and host.docker.internal inside the container, but I cannot seem to get UDP traffic to move from the container to the host. I cannot use host mode networking as I need to keep the internal ports isolated. My intent is to have multiple containers running where they all use the same internal container port (14550) with mapped external ports (i.e. 14551, 14552, etc.).

Is this not possible with Docker on MacOS?

Of course, because you are sending packets to the container itself, not the host.

You are in a virtual machine so even if iperf send packets to all IP addresses, that is still all in the container, not on the host.

Now that should work in Docker Desktop regardless of what por forward rules you have as those are only for traffic from the outside world to the container IP. Traffic from the container to the outside world doesn’t need any special config. You just need to have access to the IP to which you want to send requests and host.docker.internal will point to 127.0.0.1 on the physical host (Mac). I tested with netcat and worked. I sent a simple HELLO.

On Mac:

nc -u -l 2399

In another terminal:

docker run --rm nicolaka/netshoot nc -u host.docker.internal 2399

I typed HELLO and pressed enter. HELLO appeared in the other terminal. Can you check if that works on your machine?

@rimelek thanks for the response. So in my example, I actually tried 0.0.0.0, localhost, 127.0.0.1, and host.docker.internal and none of them worked. When doing this, I can run tcpdump and see the packets being generated in the docker container, but they do not get forwarded to the host.

I tried your example you provided, and it does not work either. See the attached screenshot. From eveything I have read, your example should work… and since you have it working on your mac, then it really points to some configuration on my mac. I am running docker desktop 4.3.90 with engine 28.0.1. My MacOS is version Sequoia 15.3.2. Any idea what could be causing the issue?

I am confused about your comment

Now that should work in Docker Desktop regardless of what por forward rules you have as those are only for traffic from the outside world to the container IP.

I did not realize that the port forwarding rules worked that way. So for example, if I am using bridge-mode and send a UDP packet from inside the container to 14550 and I want it to come out on the host at 14551, don’t I need a rule like -p 14551:14550/udp?

Thanks for the help.

Unfortunately, I don’t. I use and like my Mac, but I haven’t learned much about its networking and firewalls. And since the traffic is forwarded to the host’s loopback interface when you use host.docker.internal, I don’t see how it could be blocked by Mac. You can try changing some configurations in Docker Desktop like Virtual Machine Manager (I use the beta Docker VMM), or “Use containerd for pulling and storing images” (I have it enabled), disable features you don’t need, restart Docker Desktop and your Mac. But I’m not sure why any of these would change how network traffic works.

Port forwarding is like when you have a router in your LAN at home and you have a public IP, but you want to allow someone to access to one of your machines inside so you forward a port to your machine to the required port where your server is running for example. Docker uses port forwarding for the same reason, except it i the local Docker network in which you have a container and not a machine in a LAN network. You don’t need t forward a public port to your internal machine to be able to access port 443 on a server to read this forum for example :slight_smile: