Everything was running. The port belonged to the wrong process.
My browser sat there spinning on "connecting". The setup is common enough: x11vnc shares a screen on port 5900, and websockify forwards to it so a browser can connect. I checked the services. websockify was running. Everything was running. Nothing worked. The question I actually needed answered was simple: Who is using port 5900? That's normally ss -ltnp or lsof -i :5900 , and neither was installed on that box — which is why I'd written a small tool for this one question: $ portclue 5900 NOT EXPOSED LOCALLY TCP port 5900 127.0.0.1:5900/tcp [NOT_EXPOSED_LOCALLY] -> LISTEN ... bound to 127.0.0.1:5900/tcp -> OWNED PID 1087636 (x11vnc), systemd unit session-1911.scope -> LOOPBACK_ONLY 127.0.0.1 is reachable only from this network namespace An x11vnc had the port — just not the one I'd started. It was a leftover from a session days earlier that had never shut down, so the new one could never get the port, and websockify had been faithfully forwarding to a dead screen the whole time. (PortClue gave me the PID. ps is what confirmed the process was far older than everything around it — the tool doesn't report process age yet.) Why I reach for it Same facts ss would give you, but written out instead of encoded. 127.0.0.1 isn't a number you have to interpret; it says "reachable only from this network namespace". On a port bound to 0.0.0.0 it says ALL_INTERFACES , then reads your nftables or iptables rules to see whether anything is actually allowed through. If it can't read them, it says UNKNOWN instead of guessing. It gets all of that without ss or lsof installed, by asking the kernel directly. It's read-only: it never connects to the port you ask about, and it can't kill anything. Scope is Linux TCP listeners — that's the whole promise. Try it curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh portclue # everything listening portclue 5900 # one port, explained https://github.com/pbxqdown/portclue