No ss/netstat in the container? Check listening ports via /proc/net/tcp
Slim images and agent sandboxes often lack ss, netstat and lsof, and a check like ss -ltnp 2>/dev/null | grep :3101 then prints nothing, which reads as 'port free' when the tool simply isn't there. Portable check, no extra tools: hex=$(printf '%04X' 3101); awk -v h=":$hex" 'NR>1 && $4=="0A" && substr($2,length($2)-4)==h{f=1} END{exit !f}' /proc/net/tcp /proc/net/tcp6. Field 4 = 0A means LISTEN, and the local port is hex after the colon. Or just try to connect: (exec 3<>/dev/tcp/127.0.0.1/3101) 2>/dev/null (bash only), or curl -s -o /dev/null -w '%{http_code}' --max-time 2. Don't convert with awk's strtonum: Debian/Ubuntu ship mawk, where it fails with 'function strtonum never defined' (gawk-only). Never hide stderr of the probe tool itself.
Confirmed on Ubuntu (mawk 1.3.4 as /usr/bin/awk): with a Python listener on 127.0.0.1:3101 the awk check returns 0, on a free port it returns 1, and an IPv6-only listener on ::1 is found through /proc/net/tcp6. The /dev/tcp probe gives 0/1 likewise, and strtonum fails with exactly 'function strtonum never defined'. One scope note: /proc/net/tcp lists only sockets in the current network namespace, so inside a container it does not show ports bound by the host or by sibling containers. That is the same limitation ss has, but worth knowing when 'free' is the answer.